LP 1212456 customize items out display
authorBill Erickson <berick@esilibrary.com>
Wed, 14 Aug 2013 18:00:59 +0000 (14:00 -0400)
committerDan Wells <dbw2@calvin.edu>
Mon, 23 Sep 2013 21:44:22 +0000 (17:44 -0400)
Control when lost, longoverdue, and claimsreturn'ed items display in the
top vs bottom list in the items out interface.  Also, control when such
circs should be hidden when checked in, regardless of whether the
transaction is still open (from fines, etc.).

ui.circ.items_out.lost
ui.circ.items_out.longoverdue
ui.circ.items_out.claimsreturned

The values for the settings are bit flags.

1 = show in top list
2 = show in bottom list
4 = hide when checked in

The magic numbers for admins to enter are:

1 = top list, then bottom list (if xact is open)
2 = bottom list, then bottom list (if xact is open)
5 = top list, hide when checked in
6 = bottom list, hide when checked in

Signed-off-by: Bill Erickson <berick@esilibrary.com>
Conflicts:

Open-ILS/src/sql/Pg/950.data.seed-values.sql

Signed-off-by: Chris Sharp <csharp@georgialibraries.org>
Signed-off-by: Dan Wells <dbw2@calvin.edu>
Open-ILS/src/sql/Pg/950.data.seed-values.sql
Open-ILS/src/sql/Pg/upgrade/XXXX.data.yaous-items-out-by-stop-fines.sql [new file with mode: 0644]
Open-ILS/web/opac/locale/en-US/lang.dtd
Open-ILS/xul/staff_client/server/patron/items.js

index 9e913c3..be69078 100644 (file)
@@ -13408,6 +13408,7 @@ VALUES (
     TRUE
 );
 
+
 INSERT INTO config.org_unit_setting_type
     (name, grp, datatype, label, description)
 VALUES (
@@ -13429,3 +13430,65 @@ VALUES (
     )
 );
 
+
+INSERT INTO config.org_unit_setting_type 
+    (name, grp, datatype, label, description)
+VALUES (
+    'ui.circ.items_out.longoverdue', 'gui', 'integer',
+    oils_i18n_gettext(
+        'ui.circ.items_out.longoverdue',
+        'Items Out Long-Overdue display setting',
+        'coust',
+        'label'
+    ),
+    oils_i18n_gettext(
+        'ui.circ.items_out.longoverdue',
+'Value is a numeric code, describing which list the circulation '||
+'should appear while checked out and whether the circulation should '||
+'continue to appear in the bottom list, when checked in with '||
+'oustanding fines.  '||
+'1 = top list, bottom list.  2 = bottom list, bottom list.  ' ||
+'5 = top list, do not display.  6 = bottom list, do not display.',
+        'coust',
+        'description'
+    )
+), (
+    'ui.circ.items_out.lost', 'gui', 'integer',
+    oils_i18n_gettext(
+        'ui.circ.items_out.lost',
+        'Items Out Lost display setting',
+        'coust',
+        'label'
+    ),
+    oils_i18n_gettext(
+        'ui.circ.items_out.lost',
+'Value is a numeric code, describing which list the circulation '||
+'should appear while checked out and whether the circulation should '||
+'continue to appear in the bottom list, when checked in with '||
+'oustanding fines.  '||
+'1 = top list, bottom list.  2 = bottom list, bottom list.  ' ||
+'5 = top list, do not display.  6 = bottom list, do not display.',
+        'coust',
+        'description'
+    )
+), (
+    'ui.circ.items_out.claimsreturned', 'gui', 'integer',
+    oils_i18n_gettext(
+        'ui.circ.items_out.claimsreturned',
+        'Items Out Claims Returned display setting',
+        'coust',
+        'label'
+    ),
+    oils_i18n_gettext(
+        'ui.circ.items_out.claimsreturned',
+'Value is a numeric code, describing which list the circulation '||
+'should appear while checked out and whether the circulation should '||
+'continue to appear in the bottom list, when checked in with '||
+'oustanding fines.  '||
+'1 = top list, bottom list.  2 = bottom list, bottom list.  ' ||
+'5 = top list, do not display.  6 = bottom list, do not display.',
+        'coust',
+        'description'
+    )
+);
+
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.data.yaous-items-out-by-stop-fines.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.data.yaous-items-out-by-stop-fines.sql
new file mode 100644 (file)
index 0000000..6282c4e
--- /dev/null
@@ -0,0 +1,66 @@
+BEGIN;
+
+-- SELECT evergreen.upgrade_deps_block_check('', :eg_version);
+
+INSERT INTO config.org_unit_setting_type 
+    (name, grp, datatype, label, description)
+VALUES (
+    'ui.circ.items_out.longoverdue', 'gui', 'integer',
+    oils_i18n_gettext(
+        'ui.circ.items_out.longoverdue',
+        'Items Out Long-Overdue display setting',
+        'coust',
+        'label'
+    ),
+    oils_i18n_gettext(
+        'ui.circ.items_out.longoverdue',
+'Value is a numeric code, describing which list the circulation '||
+'should appear while checked out and whether the circulation should '||
+'continue to appear in the bottom list, when checked in with '||
+'oustanding fines.  '||
+'1 = top list, bottom list.  2 = bottom list, bottom list.  ' ||
+'5 = top list, do not display.  6 = bottom list, do not display.',
+        'coust',
+        'description'
+    )
+), (
+    'ui.circ.items_out.lost', 'gui', 'integer',
+    oils_i18n_gettext(
+        'ui.circ.items_out.lost',
+        'Items Out Lost display setting',
+        'coust',
+        'label'
+    ),
+    oils_i18n_gettext(
+        'ui.circ.items_out.lost',
+'Value is a numeric code, describing which list the circulation '||
+'should appear while checked out and whether the circulation should '||
+'continue to appear in the bottom list, when checked in with '||
+'oustanding fines.  '||
+'1 = top list, bottom list.  2 = bottom list, bottom list.  ' ||
+'5 = top list, do not display.  6 = bottom list, do not display.',
+        'coust',
+        'description'
+    )
+), (
+    'ui.circ.items_out.claimsreturned', 'gui', 'integer',
+    oils_i18n_gettext(
+        'ui.circ.items_out.claimsreturned',
+        'Items Out Claims Returned display setting',
+        'coust',
+        'label'
+    ),
+    oils_i18n_gettext(
+        'ui.circ.items_out.claimsreturned',
+'Value is a numeric code, describing which list the circulation '||
+'should appear while checked out and whether the circulation should '||
+'continue to appear in the bottom list, when checked in with '||
+'oustanding fines.  '||
+'1 = top list, bottom list.  2 = bottom list, bottom list.  ' ||
+'5 = top list, do not display.  6 = bottom list, do not display.',
+        'coust',
+        'description'
+    )
+);
+
+COMMIT;
index 6e9e3a5..dafd068 100644 (file)
 <!ENTITY staff.patron_navbar.other.accesskey 'o'>
 <!ENTITY staff.patron_navbar.items 'Items Out'>
 <!ENTITY staff.patron_navbar.items.accesskey 'I'>
-<!ENTITY staff.patron_navbar.items.problem_items.caption 'Lost, Claimed Returned, Long Overdue, Has Unpaid Billings'>
+<!ENTITY staff.patron_navbar.items.problem_items.caption 'Other/Special Circulations'>
 <!ENTITY staff.patron_navbar.refresh 'Refresh'>
 <!ENTITY staff.patron_navbar.refresh.accesskey ''>
 <!ENTITY staff.patron_navbar.retrieve 'Retrieve Patron'>
index afe6dcd..f655944 100644 (file)
@@ -537,7 +537,14 @@ patron.items.prototype = {
                         default: throw(robj);
                     }
                 } else {
-                    obj.refresh(retrieve_ids[i].circ_id,true);
+                    var c = obj.item_out_display.lost;
+                    if (1 & c) {
+                        // stay in top list, force reload
+                        obj.refresh(retrieve_ids[i].circ_id, false, true);
+                    } else {
+                        // move to bottom list (reload is automatic)
+                        obj.refresh(retrieve_ids[i].circ_id, true);
+                    }
                 }
             }
         } catch(E) {
@@ -577,6 +584,7 @@ patron.items.prototype = {
             if (my_xulG.complete) {
                 var barcodes = util.functional.map_list(retrieve_ids,function(o){return o.barcode;});
                 var do_not_move_these = {};
+                var force_reload = {};
                 for (var i = 0; i < barcodes.length; i++) {
                     var robj = obj.network.simple_request(
                         'MARK_ITEM_CLAIM_RETURNED', 
@@ -597,10 +605,22 @@ patron.items.prototype = {
                         if (robj.textcode == 'PATRON_EXCEEDS_CLAIMS_RETURN_COUNT') {
                             do_not_move_these[ barcodes[i] ] = true;
                         }
+                    } else if (robj == '1') { // success
+                        // if claimsreturned items should display in the
+                        // top list, tell refresh() to keep them there
+                        var c = obj.item_out_display.claimsreturned;
+                        if (1 & c) {
+                            do_not_move_these[ barcodes[i] ] = true;
+                            force_reload[barcodes[i]] = true;
+                        }
                     }
                 }
                 for (var i = 0; i < retrieve_ids.length; i++) {
-                    obj.refresh(retrieve_ids[i].circ_id, !do_not_move_these[ retrieve_ids[i].barcode ]);
+                    obj.refresh(
+                        retrieve_ids[i].circ_id, 
+                        !do_not_move_these[ retrieve_ids[i].barcode ], 
+                        force_reload[ retrieve_ids[i].barcode ]
+                    );
                 }
             }
         } catch(E) {
@@ -879,7 +899,7 @@ patron.items.prototype = {
         );
     },
 
-    'refresh' : function(circ_id,move_to_bottom_list) {
+    'refresh' : function(circ_id,move_to_bottom_list, reload) {
         var obj = this;
         try {
             var nparams = obj.list_circ_map[circ_id];
@@ -888,6 +908,11 @@ patron.items.prototype = {
                 var nparams2 = obj.list2.append( { 'row' : { 'my' : { 'circ_id' : circ_id } },  'to_bottom' : true, 'which_list' : 1 } );
                 obj.list_circ_map[circ_id] = nparams2; 
             } else {
+                if (reload) {
+                    // circ is not changing lists, but we need to re-fetch 
+                    // it from the server.  removing the circ forces a refresh
+                    nparams.row.my.circ = null; 
+                }
                 var which_list = nparams.which_list;
                 switch(which_list) {
                     case 1:
@@ -913,29 +938,85 @@ patron.items.prototype = {
         } else {
             obj.checkouts = [];
             obj.checkouts2 = [];
+
+            obj.item_out_display = {
+                lost : Number(obj.data.hash.aous[
+                    'ui.circ.items_out.lost']) || 2,
+                longoverdue : Number(obj.data.hash.aous[
+                    'ui.circ.items_out.longoverdue']) || 2,
+                claimsreturned : Number(obj.data.hash.aous[
+                    'ui.circ.items_out.claimsreturned']) || 2
+            };
+
+            // items still circulating
             var robj = obj.network.simple_request(
                 'FM_CIRC_RETRIEVE_VIA_USER.authoritative',
                 [ ses(), obj.patron_id ]
             );
+
             if (typeof robj.ilsevent!='undefined') {
-                obj.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.items.retrieve.err_retrieving_circulations'),E);
-            } else {
-                obj.checkouts = obj.checkouts.concat( robj.overdue );
-                obj.checkouts = obj.checkouts.concat( robj.out );
-                obj.checkouts2 = obj.checkouts2.concat( robj.lost );
-                obj.checkouts2 = obj.checkouts2.concat( robj.claims_returned );
-                obj.checkouts2 = obj.checkouts2.concat( robj.long_overdue );
+                obj.error.standard_unexpected_error_alert($("patronStrings").getString(
+                    'staff.patron.items.retrieve.err_retrieving_circulations'),E);
+                return;
             }
-            var robj = obj.network.simple_request(
-                'FM_CIRC_IN_WITH_FINES_VIA_USER.authoritative',
-                [ ses(), obj.patron_id ]
-            );
-            if (typeof robj.ilsevent!='undefined') {
-                obj.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.items.retrieve.err_retrieving_circulations'),E);
+
+            obj.checkouts = obj.checkouts.concat(robj.out);
+            obj.checkouts = obj.checkouts.concat(robj.overdue);
+
+            // open circs are added to list one or two based on config.
+            // closed circs added to list 2 only if configured, otherwise
+            // they are added to no list
+            function promote_circs(list, stop_fines, open) {
+                var code = obj.item_out_display[stop_fines];
+                if (open) {
+                    if (1 & code) { // bitflag 1 == top list
+                        obj.checkouts = obj.checkouts.concat(list);
+                    } else {
+                        obj.checkouts2 = obj.checkouts2.concat(list);
+                    }
+                } else {
+                    if (4 & code) return;  // bitflag 4 == hide on checkin
+                    obj.checkouts2 = obj.checkouts2.concat(list);
+                }
+            }
+
+            promote_circs(robj.lost, 'lost', true);
+            promote_circs(robj.long_overdue, 'longoverdue', true);
+            promote_circs(robj.claims_returned, 'claimsreturned', true);
+            
+            if (obj.item_out_display.lost & 4 &&
+                obj.item_out_display.longoverdue & 4 &&
+                obj.item_out_display.claimsreturned & 4) {
+                // all types are configured to be hidden once checked in, 
+                // so there is no need to fetch the checked in circs.
+
+                if (obj.item_out_display.lost & 1 &&
+                    obj.item_out_display.longoverdue & 1 &&
+                    obj.item_out_display.claimsreturned & 1) {
+                    // additionally, if all types are configured to display
+                    // in the top list while checked out, nothing will
+                    // ever appear in the bottom list, so we can hide
+                    // the bottom list from the UI.
+
+                    $('splitter').setAttribute('hidden', true);
+                    $('after_splitter').setAttribute('hidden', true);
+                }
+
             } else {
-                obj.checkouts2 = obj.checkouts2.concat( robj.lost );
-                obj.checkouts2 = obj.checkouts2.concat( robj.claims_returned );
-                obj.checkouts2 = obj.checkouts2.concat( robj.long_overdue );
+                var robj = obj.network.simple_request(
+                    'FM_CIRC_IN_WITH_FINES_VIA_USER.authoritative',
+                    [ ses(), obj.patron_id ]
+                );
+
+                if (typeof robj.ilsevent!='undefined') {
+                    obj.error.standard_unexpected_error_alert($("patronStrings").getString(
+                        'staff.patron.items.retrieve.err_retrieving_circulations'),E);
+                    return;
+                }
+
+                promote_circs(robj.lost, 'lost');
+                promote_circs(robj.long_overdue, 'longoverdue');
+                promote_circs(robj.claims_returned, 'claimsreturned');
             }
         }