[open-ils-commits] r15644 - in trunk/Open-ILS: src/perlmods/OpenILS/Application/Acq web/css/skin/default web/js/dojo/openils web/js/dojo/openils/User web/js/dojo/openils/User/nls web/js/dojo/openils/acq/nls web/js/ui/default/acq/common web/templates/default/acq/common (senator)

svn at svn.open-ils.org svn at svn.open-ils.org
Fri Feb 26 19:07:41 EST 2010


Author: senator
Date: 2010-02-26 19:07:40 -0500 (Fri, 26 Feb 2010)
New Revision: 15644

Added:
   trunk/Open-ILS/web/js/dojo/openils/User/
   trunk/Open-ILS/web/js/dojo/openils/User/nls/
   trunk/Open-ILS/web/js/dojo/openils/User/nls/User.js
Modified:
   trunk/Open-ILS/src/perlmods/OpenILS/Application/Acq/Picklist.pm
   trunk/Open-ILS/web/css/skin/default/acq.css
   trunk/Open-ILS/web/js/dojo/openils/User.js
   trunk/Open-ILS/web/js/dojo/openils/acq/nls/acq.js
   trunk/Open-ILS/web/js/ui/default/acq/common/li_table.js
   trunk/Open-ILS/web/templates/default/acq/common/li_table.tt2
Log:
Acq: View and manage distrib formula applications for a given lineitem

When distribution formulas are applied, each application is represented by an
icon in a new table in the lineitem copies interface.


Modified: trunk/Open-ILS/src/perlmods/OpenILS/Application/Acq/Picklist.pm
===================================================================
--- trunk/Open-ILS/src/perlmods/OpenILS/Application/Acq/Picklist.pm	2010-02-25 20:58:10 UTC (rev 15643)
+++ trunk/Open-ILS/src/perlmods/OpenILS/Application/Acq/Picklist.pm	2010-02-27 00:07:40 UTC (rev 15644)
@@ -474,4 +474,57 @@
     return undef;
 }
 
+__PACKAGE__->register_method(
+	method => "ranged_distrib_formula_applications",
+	api_name => "open-ils.acq.distribution_formula_application.ranged.retrieve",
+    stream => 1,
+	signature => {
+        desc => "Ranged distribution formulas applications, fleshed with formulas and users",
+        params => [
+            {desc => "Authentication token", type => "string"},
+            {desc => "Lineitem Id", type => "number"}
+        ],
+        return => {desc => "List of distribution formula applications"}
+    }
+);
+
+sub ranged_distrib_formula_applications {
+    my ($self, $conn, $auth, $li_id) = @_;
+
+    my $e = new_editor("authtoken" => $auth);
+    return $e->event unless $e->checkauth;
+
+    my $li = $e->retrieve_acq_lineitem([
+        $li_id, {
+            "flesh" => 1,
+            "flesh_fields" => {"jub" => [qw/purchase_order picklist/]}
+        }
+    ]) or return $e->die_event;
+
+    if ($li->picklist) {
+        return $e->die_event unless $e->allowed(
+            "VIEW_PICKLIST", $li->picklist->org_unit
+        );
+    } elsif ($li->purchase_order) {
+        return $e->die_event unless $e->allowed(
+            "VIEW_PURCHASE_ORDER", $li->purchase_order->ordering_agency
+        );
+    } else {
+        # For the moment no use cases are forseen for using this
+        # method with LIs that don't belong to a PL or a PO.
+        $e->disconnect;
+        return new OpenILS::Event("BAD_PARAMS", "note" => "Freestanding LI");
+    }
+
+    my $dfa = $e->search_acq_distribution_formula_application([
+        {"lineitem" => $li_id},
+        {"flesh" => 1, "flesh_fields" => {"acqdfa" => [qw/formula creator/]}}
+    ]);
+
+    $conn->respond($_) foreach (@$dfa);
+
+    $e->disconnect;
+    undef;
+}
+
 1;

Modified: trunk/Open-ILS/web/css/skin/default/acq.css
===================================================================
--- trunk/Open-ILS/web/css/skin/default/acq.css	2010-02-25 20:58:10 UTC (rev 15643)
+++ trunk/Open-ILS/web/css/skin/default/acq.css	2010-02-27 00:07:40 UTC (rev 15644)
@@ -148,6 +148,9 @@
 .acq-lit-li-menu-left {text-align:left; width:300px;}
 .acq-lit-li-menu-right {text-align:left;}
 .acq-lit-distrib-form-use-count { color: #999; font-weight: bold; }
+#acq-lit-distrib-applied-heading { font-size: 110%; font-weight: bold; }
+.acq-lit-distrib-applied-row td { border-right: 1px #999 solid;border-bottom: 1px #999 solid; }
+.acq-lit-distrib-applied-row th { border-bottom: 1px #999 solid;padding-bottom: 4px;}
 .acq-lit-table-spacer { height:20px; }
 .acq-lit-row td[name="selector"] { width:1.5em; font-weight:bold; color:blue; font-size:110%;}
 #acq-lit-notes-tbody li { margin-bottom:10px; border:1px solid #aaa; -moz-border-radius: 5px 5px 5px 5px; }

Added: trunk/Open-ILS/web/js/dojo/openils/User/nls/User.js
===================================================================
--- trunk/Open-ILS/web/js/dojo/openils/User/nls/User.js	                        (rev 0)
+++ trunk/Open-ILS/web/js/dojo/openils/User/nls/User.js	2010-02-27 00:07:40 UTC (rev 15644)
@@ -0,0 +1,3 @@
+{
+    'FULL_NAME': "${0}, ${3} ${1} ${2} ${4}"
+}

Modified: trunk/Open-ILS/web/js/dojo/openils/User.js
===================================================================
--- trunk/Open-ILS/web/js/dojo/openils/User.js	2010-02-25 20:58:10 UTC (rev 15643)
+++ trunk/Open-ILS/web/js/dojo/openils/User.js	2010-02-27 00:07:40 UTC (rev 15644)
@@ -24,6 +24,7 @@
     dojo.require('fieldmapper.Fieldmapper');
     dojo.require('fieldmapper.OrgUtils');
     dojo.require('openils.Util');
+    dojo.requireLocalization("openils.User", "User");
 
     dojo.declare('openils.User', null, {
 
@@ -282,12 +283,27 @@
 	        else
                 _u.getPermOrgList(perm, buildTreePicker, true);
         },
+
     });
 
 	openils.User.user = null;
 	openils.User.authtoken = null;
 	openils.User.authtime = null;
     openils.User.authcookie = null;
+    openils.User.localeStrings =
+        dojo.i18n.getLocalization("openils.User", "User");
+
+    openils.User.formalName = function(u) {
+        if (!u) u = openils.User.user;
+        return dojo.string.substitute(
+            openils.User.localeStrings.FULL_NAME, [
+                u.family_name(), u.first_given_name(),
+                u.second_given_name() ?  u.second_given_name() : "",
+                u.prefix() ? u.prefix() : "",
+                u.suffix() ? u.suffix() : ""
+            ]
+        ).replace(/\s{2,}/g, " ").replace(/\s$/, "");
+    };
 }
 
 

Modified: trunk/Open-ILS/web/js/dojo/openils/acq/nls/acq.js
===================================================================
--- trunk/Open-ILS/web/js/dojo/openils/acq/nls/acq.js	2010-02-25 20:58:10 UTC (rev 15643)
+++ trunk/Open-ILS/web/js/dojo/openils/acq/nls/acq.js	2010-02-27 00:07:40 UTC (rev 15644)
@@ -22,5 +22,9 @@
 
     'UNRECEIVE_LID': "Are you sure you want to mark this copy as UN-received?",
     'CONFIRM_LI_ALERT': "An alert has been placed on the lineitem titled,\n\"${0}\":\n\n${1}\n${2}\n${3}\nChoose OK if you wish to acknowledge this alert.",
-    'ALERT_UNSELECTED': "You must choose an alert code."
+    'ALERT_UNSELECTED': "You must choose an alert code.",
+    'DFA_TIP': "<strong>Applied by</strong>: ${0}<br /><strong>When</strong>: ${1}",
+    'ITS_YOU': "You",
+    'JUST_NOW': "Just now",
+    'EXPLAIN_DFA_MGMT': "Remove record of this distribution formula usage?"
 }

Modified: trunk/Open-ILS/web/js/ui/default/acq/common/li_table.js
===================================================================
--- trunk/Open-ILS/web/js/ui/default/acq/common/li_table.js	2010-02-25 20:58:10 UTC (rev 15643)
+++ trunk/Open-ILS/web/js/ui/default/acq/common/li_table.js	2010-02-27 00:07:40 UTC (rev 15644)
@@ -4,6 +4,7 @@
 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('openils.User');
 dojo.require('openils.Util');
@@ -35,13 +36,16 @@
     this.liCache = {};
     this.plCache = {};
     this.poCache = {};
-    this.dfaCache = {};
+    this.realDfaCache = {};
+    this.virtDfaCounts = {};
+    this.virtDfaId = -1;
     this.dfeOffset = 0;
     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'));
@@ -322,7 +326,7 @@
         acqLitAlertAlertText.store = new dojo.data.ItemFileReadStore(
             {
                 "data": acqliat.toStoreData(
-                    (new openils.PermaCrud()).search(
+                    this.pcrud.search(
                         "acqliat", {"id": {"!=": null}}
                     )
                 )
@@ -625,7 +629,8 @@
         this.copyCache = {};
         this.copyWidgetCache = {};
         this.oldCopyWidgetCache = {};
-        this.dfaCache = {};
+        this.virtDfaCounts = {};
+        this.realDfaCache = {};
         this.dfeOffset = 0;
 
         acqLitSaveCopies.onClick = function() { self.saveCopyChanges(liId) };
@@ -637,6 +642,8 @@
 
         this._drawBatchCopyWidgets();
 
+        this._drawDistribApplied(liId);
+
         this._fetchDistribFormulas(
             function() {
                 openils.acq.Lineitem.fetchAttrDefs(
@@ -648,6 +655,158 @@
         );
     };
 
+    this._saveDistribAppliedTemplates = function() {
+        if (!this._appliedDistribTemplate) {
+            this._appliedDistribTemplate =
+                dojo.byId("acq-lit-distrib-applied-tbody").
+                    removeChild(dojo.byId("acq-lit-distrib-applied-row"));
+            dojo.attr(this._appliedDistribTemplate, "id");
+        }
+    };
+
+    this._drawDistribApplied = function(liId) {
+        /* Build this table while hidden to prevent rendering artifacts */
+        openils.Util.hide("acq-lit-distrib-applied-tbody");
+
+        this._saveDistribAppliedTemplates();
+
+        /* Remove any rows in the table from previous populations */
+        dojo.query("tr[formula]", "acq-lit-distrib-applied-tbody").
+            forEach(dojo.destroy);
+
+        /* Unregister all dijits previously created (for some reason this isn't
+         * covered by the above destroy calls). */
+        dijit.registry.forEach(
+            function(w) { if (/^dfa-/.test(w.id)) w.destroyRecursive(); }
+        );
+
+        /* Populate the table with our liId */
+        var total = 0;
+        fieldmapper.standardRequest(
+            ["open-ils.acq",
+            "open-ils.acq.distribution_formula_application.ranged.retrieve"],
+            {
+                "async": true,
+                "params": [self.authtoken, liId],
+                "onresponse": function(r) {
+                    var dfa = openils.Util.readResponse(r);
+                    if (dfa) {
+                        total++;
+                        self.realDfaCache[dfa.id()] = dfa;
+                        self._drawDistribAppliedUnit(dfa);
+                    }
+                },
+                "oncomplete": function() {
+                    /* Reveal built table */
+                    if (total) {
+                        openils.Util.show(
+                            "acq-lit-distrib-applied-tbody", "table-row-group"
+                        );
+                    }
+                }
+            }
+        );
+    };
+
+    this._drawDistribAppliedUnit = function(dfa) {
+        var new_row = false;
+        var row = dojo.query(
+            'tr[formula="' + dfa.formula().id() + '"]',
+            "acq-lit-distrib-applied-tbody"
+        )[0];
+
+        if (!row) {
+            new_row = true;
+            row = dojo.clone(this._appliedDistribTemplate);
+            dojo.attr(row, "formula", dfa.formula().id());
+            dojo.query("th", row)[0].innerHTML = dfa.formula().name();
+        }
+
+        var td = dojo.query("td", row)[0];
+
+        dojo.create("span", {"id": "dfa-button-" + dfa.id()}, td, "last");
+        dojo.create("span", {"id": "dfa-tip-" + dfa.id()}, td, "last");
+
+        if (new_row)
+            dojo.place(row, "acq-lit-distrib-applied-tbody", "last");
+
+        new dijit.form.Button(
+            {
+                "onClick": function() {
+                    if (confirm(localeStrings.EXPLAIN_DFA_MGMT))
+                        self.deleteDfa(dfa);
+                },
+                "label": "X",
+                /* XXX I /cannot/ make the following work in as a CSS class
+                 * for some reason. So frustrating... */
+                "style": function(id) {
+                     return (id > 0 ?
+                        "font-weight: bold; color: #c00;" :
+                        "color: #666;");
+                     }(dfa.id()) + "margin: 0 6px;display: inline;"
+            }, "dfa-button-" + dfa.id()
+        );
+        new dijit.Tooltip(
+            {
+                "connectId": ["dfa-button-" + dfa.id()],
+                "label": dojo.string.substitute(
+                    localeStrings.DFA_TIP, dfa.id() > 0 ? [
+                        openils.User.formalName(dfa.creator()),
+                        dojo.date.locale.format(
+                            dojo.date.stamp.fromISOString(dfa.create_time()),
+                            {"formatLength":"short"}
+                        )
+                    ] : [localeStrings.ITS_YOU, localeStrings.JUST_NOW]
+                )
+            }, "dfa-tip-" + dfa.id()
+        );
+    }
+
+    this.deleteDfa = function(dfa) {
+        if (dfa.id() > 0) { /* real */
+            this.pcrud.delete(
+                dfa, {
+                    "async": true,
+                    "oncomplete": function() {
+                        self._removeDistribApplied(dfa.id());
+                        delete self.realDfaCache[dfa.id()];
+                    }
+                }
+            );
+        } else { /* virtual */
+            if (--(this.virtDfaCounts[dfa.formula().id()]) < 0)
+            this.virtDfaCounts[dfa.formula().id()] = 0;
+            /* hasn't been saved yet, so no need to do anything server side */
+            this._removeDistribApplied(dfa.id());
+        }
+
+    };
+
+    this._removeDistribApplied = function(dfaId) {
+        var re = new RegExp("^dfa-\\w+-" + String(dfaId));
+        dijit.registry.forEach(
+            function(w) { if (re.test(w.id)) w.destroyRecursive(); }
+        );
+        this._removeDistribAppliedEmptyRows();
+    };
+
+    this._removeAllDistribAppliedVirtual = function() {
+        /* Unregister dijits */
+        dijit.registry.forEach(
+            function(w) { if (/^dfa-\w+--/.test(w.id)) w.destroyRecursive(); }
+        );
+        this._removeDistribAppliedEmptyRows();
+    };
+
+    this._removeDistribAppliedEmptyRows = function() {
+        /* Remove any rows with no DFA at all */
+        dojo.query("tr[formula] td", "acq-lit-distrib-applied-tbody").forEach(
+            function(o) {
+                if (o.childNodes.length < 1) dojo.destroy(o.parentNode);
+            }
+        );
+    };
+
     /**
      * Insert a new row into the distribution formula selection form
      */
@@ -697,9 +856,11 @@
         dojo.connect(reset, 'onClick', 
             function() {
                 self.restoreCopyFieldsBeforeDF();
-                self.dfaCache = {};
+                self.virtDfaCounts = {};
+                self.virtDfaId = -1;
                 self.dfeOffset = 0;
                 self._updateFormulaStore();
+                self._removeAllDistribAppliedVirtual();
                 reset.attr("disabled", "true");
             }
         );
@@ -765,8 +926,15 @@
         }
 
         if (entries_applied) {
-            this.dfaCache[formula.id()] = ++(this.dfaCache[formula.id()]) || 1;
+            this.virtDfaCounts[formula.id()] =
+                ++(this.virtDfaCounts[formula.id()]) || 1;
             this._updateFormulaStore();
+            this._drawDistribAppliedUnit(
+                function(df) {
+                    var dfa = new acqdfa();
+                    dfa.formula(df); dfa.id(self.virtDfaId--); return dfa;
+                }(formula)
+            );
             this.dfeOffset += entries_applied;
         };
     };
@@ -819,8 +987,8 @@
             var obj = store_data.items[key];
             obj.use_count = Number(obj.use_count); /* needed for sorting */
 
-            if (this.dfaCache[obj.id])
-                obj.use_count = obj.use_count + Number(this.dfaCache[obj.id]);
+            if (this.virtDfaCounts[obj.id])
+                obj.use_count = obj.use_count + Number(this.virtDfaCounts[obj.id]);
 
             obj.dynLabel = "<span class='acq-lit-distrib-form-use-count'>[" +
                 obj.use_count + "]</span>&nbsp; " + obj.name;
@@ -1071,10 +1239,10 @@
         this.copyTbody.removeChild(row);
     }
 
-    this._dfaCacheAsList = function() {
+    this._virtDfaCountsAsList = function() {
         var L = [];
-        for (var key in this.dfaCache) {
-            for (var i = 0; i < this.dfaCache[key]; i++)
+        for (var key in this.virtDfaCounts) {
+            for (var i = 0; i < this.virtDfaCounts[key]; i++)
                 L.push(key);
         }
         return L;
@@ -1120,7 +1288,7 @@
             );
         }
 
-        var dfa_list = this._dfaCacheAsList();
+        var dfa_list = this._virtDfaCountsAsList();
         if (dfa_list.length > 0) {
             fieldmapper.standardRequest(
                 ["open-ils.acq",
@@ -1135,7 +1303,7 @@
                     }
                 }
             );
-            this.dfaCache = {};
+            this.virtDfaCounts = {};
         }
     }
 
@@ -1239,7 +1407,7 @@
             acqLitExportAttrSelector.store = new dojo.data.ItemFileReadStore(
                 {
                     "data": acqliad.toStoreData(
-                        (new openils.PermaCrud()).search(
+                        this.pcrud.search(
                             "acqliad", {"code": li_exportable_attrs}
                         )
                     )
@@ -1573,7 +1741,6 @@
             this.realCopiesTbody.removeChild(this.realCopiesTbody.childNodes[0]);
         this.show('real-copies');
 
-        var pcrud = new openils.PermaCrud({authtoken : this.authtoken});
         this.realCopyList = [];
         this.volCache = {};
         var tabIndex = 1000;
@@ -1587,7 +1754,7 @@
             function(fullLi) {
                 li = self.liCache[li.id()] = fullLi;
 
-                pcrud.search(
+                self.pcrud.search(
                     'acp', {
                         id : li.lineitem_details().map(
                             function(item) { return item.eg_copy_id() }
@@ -1600,7 +1767,7 @@
                             var volId = copy.call_number();
                             var volume = self.volCache[volId];
                             if(!volume) {
-                                volume = self.volCache[volId] = pcrud.retrieve('acn', volId);
+                                volume = self.volCache[volId] = self.pcrud.retrieve('acn', volId);
                             }
                             self.addRealCopy(volume, copy, tabIndex++);
                         }
@@ -1669,10 +1836,9 @@
     };
 
     this.saveRealCopies = function() {
-        var pcrud = new openils.PermaCrud({authtoken : this.authtoken});
         progressDialog.show(true);
         var list = this.realCopyList.filter(function(copy) { return copy.ischanged(); });
-        pcrud.update(list, {oncomplete: function() { 
+        this.pcrud.update(list, {oncomplete: function() { 
             progressDialog.hide();
             self.show('list');
         }});

Modified: trunk/Open-ILS/web/templates/default/acq/common/li_table.tt2
===================================================================
--- trunk/Open-ILS/web/templates/default/acq/common/li_table.tt2	2010-02-25 20:58:10 UTC (rev 15643)
+++ trunk/Open-ILS/web/templates/default/acq/common/li_table.tt2	2010-02-27 00:07:40 UTC (rev 15644)
@@ -239,6 +239,19 @@
             </tbody>
 
             <tbody><tr><td class='acq-lit-table-spacer' colspan='0'/></tr></tbody>
+            <tbody id="acq-lit-distrib-applied-tbody" class="hidden">
+                <tr>
+                    <td colspan="5" id="acq-lit-distrib-applied-heading">
+                        Distribution formulas applied to this lineitem:
+                    </td>
+                </tr>
+                <tr id="acq-lit-distrib-applied-row" class="acq-lit-distrib-applied-row">
+                    <th></th>
+                    <td colspan="4"></td>
+                </tr>
+            </tbody>
+
+            <tbody><tr><td class='acq-lit-table-spacer' colspan='0'/></tr></tbody>
             <tbody style='font-weight:bold;'>
                 <tr>
                     <td style='margin-top:30px;'>Owning Branch</td>



More information about the open-ils-commits mailing list