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

svn at svn.open-ils.org svn at svn.open-ils.org
Wed Mar 31 15:38:07 EDT 2010


Author: senator
Date: 2010-03-31 15:38:02 -0400 (Wed, 31 Mar 2010)
New Revision: 16071

Modified:
   trunk/Open-ILS/src/perlmods/OpenILS/Application/Acq/Order.pm
   trunk/Open-ILS/web/js/dojo/openils/acq/nls/acq.js
   trunk/Open-ILS/web/js/ui/default/acq/common/li_table.js
Log:
Acq: Indicate funds at stop/warning balance level with color and warnings

Specifically, in the lineitem detail (copy) interface,
where there are fund dropdowns.


Modified: trunk/Open-ILS/src/perlmods/OpenILS/Application/Acq/Order.pm
===================================================================
--- trunk/Open-ILS/src/perlmods/OpenILS/Application/Acq/Order.pm	2010-03-31 17:26:09 UTC (rev 16070)
+++ trunk/Open-ILS/src/perlmods/OpenILS/Application/Acq/Order.pm	2010-03-31 19:38:02 UTC (rev 16071)
@@ -698,21 +698,55 @@
 }
 
 
-sub fund_exceeds_balance_stop_percent {
-    return fund_exceeds_balance_percent(
-        @_, "balance_stop_percent", "ACQ_FUND_EXCEEDS_STOP_PERCENT"
-    );
-}
+__PACKAGE__->register_method(
+	"method" => "fund_exceeds_balance_percent_api",
+	"api_name" => "open-ils.acq.fund.check_balance_percentages",
+	"signature" => {
+        "desc" => q/Determine whether a given fund exceeds its defined
+            "balance stop and warning percentages"/,
+        "params" => [
+            {"desc" => "Authentication token", "type" => "string"},
+            {"desc" => "Fund ID", "type" => "number"},
+            {"desc" => "Theoretical debit amount (optional)",
+                "type" => "number"}
+        ],
+        "return" => {"desc" => q/An array of two values, for stop and warning,
+            in that order: 1 if fund exceeds that balance percentage, else 0/}
+    }
+);
 
-sub fund_exceeds_balance_warning_percent {
-    return fund_exceeds_balance_percent(
-        @_, "balance_warning_percent", "ACQ_FUND_EXCEEDS_WARN_PERCENT"
-    );
+sub fund_exceeds_balance_percent_api {
+    my ($self, $conn, $auth, $fund_id, $debit_amount) = @_;
+
+    $debit_amount ||= 0;
+
+    my $e = new_editor("authtoken" => $auth);
+    return $e->die_event unless $e->checkauth;
+
+    my $fund = $e->retrieve_acq_fund($fund_id) or return $e->die_event;
+    return $e->die_event unless $e->allowed("VIEW_FUND", $fund->org);
+
+    my $result = [
+        fund_exceeds_balance_percent($fund, $debit_amount, $e, "stop"),
+        fund_exceeds_balance_percent($fund, $debit_amount, $e, "warning")
+    ];
+
+    $e->disconnect;
+    return $result;
 }
 
 sub fund_exceeds_balance_percent {
-    my ($fund, $debit_amount, $e, $method_name, $event_name) = @_;
+    my ($fund, $debit_amount, $e, $which) = @_;
 
+    my ($method_name, $event_name) = @{{
+        "warning" => [
+            "balance_warning_percent", "ACQ_FUND_EXCEEDS_WARN_PERCENT"
+        ],
+        "stop" => [
+            "balance_stop_percent", "ACQ_FUND_EXCEEDS_STOP_PERCENT"
+        ]
+    }->{$which}};
+
     if ($fund->$method_name) {
         my $balance =
             $e->search_acq_fund_combined_balance({"fund" => $fund->id})->[0];
@@ -752,10 +786,12 @@
     my $fund = $mgr->editor->retrieve_acq_fund($args{fund}) or return 0;
 
     return 0 if
-        fund_exceeds_balance_stop_percent($fund, $args{"amount"}, $mgr->editor);
+        fund_exceeds_balance_percent(
+            $fund, $args{"amount"}, $mgr->editor, "stop"
+        );
     return 0 if
-        $dry_run and fund_exceeds_balance_warning_percent(
-            $fund, $args{"amount"}, $mgr->editor
+        $dry_run and fund_exceeds_balance_percent(
+            $fund, $args{"amount"}, $mgr->editor, "warning"
         );
 
     my $debit = Fieldmapper::acq::fund_debit->new;

Modified: trunk/Open-ILS/web/js/dojo/openils/acq/nls/acq.js
===================================================================
--- trunk/Open-ILS/web/js/dojo/openils/acq/nls/acq.js	2010-03-31 17:26:09 UTC (rev 16070)
+++ trunk/Open-ILS/web/js/dojo/openils/acq/nls/acq.js	2010-03-31 19:38:02 UTC (rev 16071)
@@ -53,5 +53,7 @@
     'PO_COULD_ACTIVATE' : "Yes.",
     'PO_WARNING_NO_BLOCK_ACTIVATION': "Yes; fund ${0} (${1}) would be encumbered beyond its warning level.",
     'PO_STOP_BLOCKS_ACTIVATION': "No; fund ${0} (${1}) would be encumbered beyond its stop level.",
-    'PO_FUND_WARNING_CONFIRM': "Are you sure? Did you see the warning about over-encumbering a fund?"
+    'PO_FUND_WARNING_CONFIRM': "Are you sure? Did you see the warning about over-encumbering a fund?",
+    'CONFIRM_FUNDS_AT_STOP': "One or more of the selected funds has a balance below its stop level.\nYou may not be able to activate purchase orders incorporating these copies.\nContinue?",
+    'CONFIRM_FUNDS_AT_WARNING': "One or more of the selected funds has a balance below its warning level.\nContinue?",
 }

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-03-31 17:26:09 UTC (rev 16070)
+++ trunk/Open-ILS/web/js/ui/default/acq/common/li_table.js	2010-03-31 19:38:02 UTC (rev 16071)
@@ -22,7 +22,9 @@
 const XUL_OPAC_WRAPPER = 'chrome://open_ils_staff_client/content/cat/opac.xul';
 var li_exportable_attrs = ["issn", "isbn", "upc"];
 
-var fundLabelFormat = ['${0} (${1})', 'code', 'year'];
+var fundLabelFormat = [
+    '<span class="fund_${0}">${1} (${2})</span>', 'id', 'code', 'year'
+];
 var fundSearchFormat = ['${0} (${1})', 'code', 'year'];
 
 function nodeByName(name, context) {
@@ -32,6 +34,10 @@
 
 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() {
 
@@ -40,6 +46,8 @@
     this.plCache = {};
     this.poCache = {};
     this.relCache = {};
+    this.haveFundClass = {}
+    this.fundBalanceState = {};
     this.realDfaCache = {};
     this.virtDfaCounts = {};
     this.virtDfaId = -1;
@@ -1131,14 +1139,27 @@
                         searchFilter : (field == 'fund') ? {"active": "t"} : null,
                         parentNode : dojo.query('[name='+field+']', row)[0],
                         orgLimitPerms : ['CREATE_PICKLIST'],
-                        dijitArgs : {required:false},
+                        dijitArgs : {
+                            "required": false,
+                            "labelType": (field == "fund") ? "html" : null
+                        },
+                        noCache: (field == "fund"),
                         forceSync : true
                     });
                     widget.build(
                         function(w, ww) {
+                            if (field == "fund" && w.store)
+                                self._ensureCSSFundClasses(w.store);
                             self.copyBatchWidgets[field] = w;
                         }
                     );
+                    if (field == "fund") {
+                        dojo.connect(
+                            widget.widget, "onChange", function(val) {
+                                self._updateFundSelectorStyle(widget, val);
+                            }
+                        );
+                    }
                 }
             }
         );
@@ -1234,8 +1255,9 @@
                     fmField : field,
                     labelFormat : (field == 'fund') ? fundLabelFormat : null,
                     searchFormat : (field == 'fund') ? fundSearchFormat : null,
+                    dijitArgs: {"labelType": (field == 'fund') ? "html" : null},
                     searchFilter : searchFilter,
-                    noCache: true,
+                    noCache: (field == "fund"),
                     fmClass : 'acqlid',
                     parentNode : dojo.query('[name='+field+']', row)[0],
                     orgLimitPerms : ['CREATE_PICKLIST', 'CREATE_PURCHASE_ORDER'],
@@ -1244,13 +1266,18 @@
                 widget.build(
                     // make sure we capture the value from any async widgets
                     function(w, ww) { 
+                        if (field == "fund" && w.store)
+                            self._ensureCSSFundClasses(w.store);
                         copy[field](ww.getFormattedValue()) 
                         self.copyWidgetCache[copy.id()][field] = w;
                     }
                 );
                 dojo.connect(widget.widget, 'onChange', 
                     function(val) { 
-                        if(copy.isnew() || val != copy[field]()) {
+                        if (field == "fund")
+                            self._updateFundSelectorStyle(widget, val);
+
+                        if (copy.isnew() || val != copy[field]()) {
                             // prevent setting ischanged() automatically on widget load for existing copies
                             copy[field](widget.getFormattedValue()) 
                             copy.ischanged(true);
@@ -1263,6 +1290,55 @@
         this.updateLidState(copy, row);
     };
 
+    this._ensureCSSFundClass = function(id) {
+        if (!this.fundStyleSheet) {
+            dojo.create(
+                "style", {"type": "text/css"},
+                document.getElementsByTagName("head")[0], "last"
+            );
+            this.fundStyleSheet = document.styleSheets[
+                document.styleSheets.length - 1
+            ];
+        }
+
+        var cn = "fund_" + id;
+        if (!this.haveFundClass[cn]) {
+            fieldmapper.standardRequest(
+                ["open-ils.acq", "open-ils.acq.fund.check_balance_percentages"],
+                {
+                    "params": [openils.User.authtoken, id],
+                    "async": true,
+                    "oncomplete": function(r) {
+                        r = openils.Util.readResponse(r);
+                        self.fundBalanceState[id] = r;
+                        var style = "";
+                        if (r[0] /* stop */)
+                            style = fundStyles.stop;
+                        else if (r[1] /* warning */)
+                            style = fundStyles.warning;
+                        self.fundStyleSheet.insertRule(
+                            "." + cn + " { " + style + " }",
+                            self.fundStyleSheet.cssRules.length
+                        );
+                        self.haveFundClass[cn] = true;
+                    }
+                }
+            );
+        }
+    };
+
+    this._ensureCSSFundClasses = function(store) {
+        store.fetch({
+            "query": {"id": "*"},
+            "onItem": function(o) { self._ensureCSSFundClass(o.id[0]); }
+        });
+    };
+
+    this._updateFundSelectorStyle = function(widget, fund_id) {
+        openils.Util.removeCSSClass(widget.widget.domNode, /fund_\d+/);
+        openils.Util.addCSSClass(widget.widget.domNode, "fund_" + fund_id);
+    };
+
     this.updateLidState = function(copy, row) {
         if (typeof(row) == "undefined") {
             row = dojo.query(
@@ -1444,6 +1520,28 @@
         return L;
     }
 
+    this.confirmBreachedCopyFunds = function(copies) {
+        var stop = 0, warning = 0;
+        copies.forEach(
+            function(o) {
+                if (o.fund()) {
+                    var state = self.fundBalanceState[o.fund()];
+                    if (state[0] /* stop */)
+                        stop++;
+                    else if (state[1] /* warning */)
+                        warning++;
+                }
+            }
+        );
+
+        if (stop) {
+            return confirm(localeStrings.CONFIRM_FUNDS_AT_STOP);
+        } else if (warning) {
+            return confirm(localeStrings.CONFIRM_FUNDS_AT_WARNING);
+        }
+        return true;
+    };
+
     this.saveCopyChanges = function(liId) {
         var self = this;
         var copies = [];
@@ -1459,14 +1557,17 @@
             }
         }
 
-        if (typeof(this._copy_count_cb) == "function") {
-            this._copy_count_cb(liId, total);
-        }
 
         dojo.byId('acq-lit-copy-count-label-' + liId).innerHTML = total;
 
 
         if (copies.length > 0) {
+            if (!this.confirmBreachedCopyFunds(copies))
+                return;
+
+            if (typeof(this._copy_count_cb) == "function")
+                this._copy_count_cb(liId, total);
+
             openils.Util.show("acq-lit-update-copies-progress");
             fieldmapper.standardRequest(
                 ['open-ils.acq', 'open-ils.acq.lineitem_detail.cud.batch'],



More information about the open-ils-commits mailing list