Revert "lp1908439 Auto-override enhancment"
authorMike Rylander <mrylander@gmail.com>
Fri, 3 Sep 2021 14:35:00 +0000 (10:35 -0400)
committerMike Rylander <mrylander@gmail.com>
Fri, 3 Sep 2021 14:35:00 +0000 (10:35 -0400)
This reverts commit 96e5f9d3c2a739e22485e07d9738ad52f24e60c9.

This is a feature rather than a bug fix, and should not have gone into
3.7.

Open-ILS/src/templates/staff/base_js.tt2
Open-ILS/src/templates/staff/circ/share/t_event_override_dialog.tt2
Open-ILS/web/js/ui/default/staff/circ/patron/app.js
Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js
Open-ILS/web/js/ui/default/staff/circ/services/circ.js
Open-ILS/web/js/ui/default/staff/services/op_change.js
docs/RELEASE_NOTES_NEXT/Circulation/override-dialogs.adoc [deleted file]

index f0df81e..53e6f5f 100644 (file)
@@ -136,7 +136,6 @@ UpUp.start({
     s.OP_CHANGE_PERM_MESSAGE = "[% l('Another staff member with the above permission may authorize this specific action.  Please notify your library administrator if you need this permission.  If you feel you have received this exception in error, please inform your friendly Evergreen developers or helpdesk staff of the above permission.') %]";
     s.PERM_OP_CHANGE_SUCCESS = "[% l('Permission Override Login Succeeded') %]";
     s.PERM_OP_CHANGE_FAILURE = "[% l('Permission Override Login Failed') %]";
-    s.PERM_OP_CHANGE_PERSIST = "[% l('Re-Using Permission Override Login in Batch') %]";
     s.OPT_IN_DIALOG_TITLE = "[% l('Verify Permission to Share Personal Information') %]";
     s.OPT_IN_DIALOG = "[% l('Does patron [_1], [_2] from [_3] ([_4]) consent to having their personal information shared with your library?', '{{family_name}}', '{{first_given_name}}', '{{org_name}}', '{{org_shortname}}') %]";
     s.OPT_IN_RESTRICTED = "[% l("This patron's record is not viewable at your library.") %]";
index f3f1317..398796f 100644 (file)
@@ -2,45 +2,35 @@
   <div class="modal-header">
     <button type="button" class="close" 
       ng-click="cancel()" aria-hidden="true">&times;</button>
-    <h4 ng-if="action == 'checkout'" class="modal-title">
+    <h4 class="modal-title">
       [% l('Exceptions occurred during checkout.') %]
     </h4>
-    <h4 ng-if="action == 'renew'" class="modal-title">
-      [% l('Exceptions occurred during renewal.') %]
-    </h4>
   </div>
   <div class="modal-body">
     <div ng-repeat="evt in events">
-      <div ng-class="{ 'panel': true, 'panel-danger': !formdata.event_ui_data[evt.ilsevent].overridable, 'panel-warning': formdata.event_ui_data[evt.ilsevent].overridable }">
+      <div class="panel panel-danger">
         <div class="panel-heading">{{evt.textcode}}</div>
         <div class="panel-body">
           <div ng-if="copy_barcode" class="strong-text-2">{{copy_barcode}}</div>
           {{evt.desc}}
-          <div ng-if="evt.textcode == 'ITEM_ON_HOLDS_SHELF'">
-            <a target="_blank" href="[% ctx.base_path %]/staff/circ/patron/{{patronID}}/checkout">{{patronName}}</a>.
+          <div ng-if="evt.textcode == 'ITEM_ON_HOLDS_SHELF'"> 
+              <a target="_blank" href="[% ctx.base_path %]/staff/circ/patron/{{patronID}}/checkout">{{patronName}}</a>.
             <div>
-              <label><input type="checkbox" ng-model="formdata.clearHold"/>
-                [% l('Cancel this hold upon checkout?') %]</label>
-            </div>
-          </div>
-          <div ng-if="formdata.event_ui_data[evt.ilsevent].overridable">
-              <label ng-class="{ 'acknowledged': formdata.nonoverridable }"><input type="checkbox" ng-disabled="formdata.nonoverridable" ng-model="formdata.event_ui_data[evt.ilsevent].checkbox"/>
-                [% l('Automatically override for subsequent items?') %]</label>
-          </div>
-          <div ng-if="!formdata.event_ui_data[evt.ilsevent].overridable">
-              <label><input type="checkbox" ng-model="formdata.event_ui_data[evt.ilsevent].checkbox"/>
-                [% l('Automatically skip items with this error?') %]</label>
-          </div>
+               <label><input type="checkbox" ng-model="formdata.clearHold"/> 
+               [% l('Cancel this hold upon checkout?') %]</label>
+           </div>
+
+         </div>
         </div>
       </div>
     </div>
   </div>
   <div class="modal-footer">
+    <i ng-if="auto_override">[% |l %]If overridden, subsequent checkouts during this patron's 
+ session will auto-override this event[% END %]</i>
     <br/><br/>
-    <input type="submit" class="btn btn-primary" ng-disabled="formdata.nonoverridable"
+    <input type="submit" class="btn btn-primary" 
         value="[% l('Force Action?') %]"/>
-    <button class="btn" 
-      ng-click="skip($event)">[% l('Skip?') %]</button>
     <button class="btn btn-warning" 
       ng-click="cancel($event)">[% l('Cancel') %]</button>
   </div>
index 1cfcba6..736c938 100644 (file)
@@ -225,8 +225,8 @@ angular.module('egPatronApp', ['ngRoute', 'ui.bootstrap', 'egUserBucketMod',
  *
  * */
 .controller('PatronCtrl',
-       ['$scope','$q','$location','$filter','egCore','egNet','egUser','egAlertDialog','egConfirmDialog','egPromptDialog','patronSvc','egCirc',
-function($scope,  $q , $location , $filter , egCore , egNet , egUser , egAlertDialog , egConfirmDialog , egPromptDialog , patronSvc , egCirc) {
+       ['$scope','$q','$location','$filter','egCore','egNet','egUser','egAlertDialog','egConfirmDialog','egPromptDialog','patronSvc',
+function($scope,  $q , $location , $filter , egCore , egNet , egUser , egAlertDialog , egConfirmDialog , egPromptDialog , patronSvc) {
 
     $scope.is_patron_edit = function() {
         return Boolean($location.path().match(/patron\/\d+\/edit$/));
@@ -283,10 +283,6 @@ function($scope,  $q , $location , $filter , egCore , egNet , egUser , egAlertDi
         $scope.aous = egCore.env.aous;
         $scope.auth_user_id = egCore.auth.user().id();
 
-        if (tab == 'search') {
-            egCirc.reset(); // clear out auto-override and auto-skip selections when switching patrons
-        }
-
         if (patron_id) {
             $scope.patron_id = patron_id;
             return patronSvc.setPrimary($scope.patron_id)
index 16c04c9..d8cc9da 100644 (file)
@@ -493,35 +493,11 @@ function($scope , $q , $routeParams , $timeout , egCore , egUser , patronSvc ,
 
         return egConfirmDialog.open(msg, barcodes.join(' '), {}).result
         .then(function() {
-            window.oils_cancel_batch = false;
-            window.oils_inside_batch = true;
-            function batch_cleanup() {
-                if (window.oils_inside_batch && window.oils_op_change_within_batch) {
-                    window.oils_op_change_undo_func();
-                }
-                window.oils_inside_batch = false;
-                window.oils_op_change_within_batch = false;
-                reset_page();
-            }
             function do_one() {
                 var bc = barcodes.pop();
-                if (!bc) {
-                    batch_cleanup();
-                    return;
-                }
-                if (window.oils_op_change_within_batch) {
-                    window.oils_op_change_toast_func();
-                }
+                if (!bc) { reset_page(); return }
                 // finally -> continue even when one fails
-                egCirc.renew({copy_barcode : bc}).finally(function() {
-                    if (!window.oils_cancel_batch) {
-                        do_one();
-                    } else {
-                        console.log('batch cancelled');
-                        batch_cleanup();
-                        return;
-                    }
-                });
+                egCirc.renew({copy_barcode : bc}).finally(do_one);
             }
             do_one();
         });
index 975e3ce..6f22aa8 100644 (file)
@@ -13,9 +13,7 @@ function($uibModal , $q , egCore , egAlertDialog , egConfirmDialog,  egAddCopyAl
 
     var service = {
         // auto-override these events after the first override
-        auto_override_circ_events : {},
-        // auto-skip these events after the first skip
-        auto_skip_circ_events : {},
+        auto_override_checkout_events : {},
         require_initials : false,
         never_auto_print : {
             hold_shelf_slip : false,
@@ -48,23 +46,37 @@ function($uibModal , $q , egCore , egAlertDialog , egConfirmDialog,  egAddCopyAl
     });
 
     service.reset = function() {
-        service.auto_override_circ_events = {};
-        service.auto_skip_circ_events = {};
+        service.auto_override_checkout_events = {};
     }
 
-    // these events cannot be overriden
-    service.nonoverridable_events = [
-        'ACTION_CIRCULATION_NOT_FOUND',
-        'ACTOR_USER_NOT_FOUND',
-        'ASSET_COPY_NOT_FOUND',
-        'PATRON_INACTIVE',
-        'PATRON_CARD_INACTIVE',
-        'PATRON_ACCOUNT_EXPIRED',
-        'PERM_FAILURE' // should be handled elsewhere
+    // these events can be overridden by staff during checkout
+    service.checkout_overridable_events = [
+        'PATRON_EXCEEDS_OVERDUE_COUNT',
+        'PATRON_EXCEEDS_CHECKOUT_COUNT',
+        'PATRON_EXCEEDS_FINES',
+        'PATRON_EXCEEDS_LONGOVERDUE_COUNT',
+        'PATRON_BARRED',
+        'CIRC_EXCEEDS_COPY_RANGE',
+        'ITEM_DEPOSIT_REQUIRED',
+        'ITEM_RENTAL_FEE_REQUIRED',
+        'PATRON_EXCEEDS_LOST_COUNT',
+        'COPY_CIRC_NOT_ALLOWED',
+        'COPY_NOT_AVAILABLE',
+        'COPY_IS_REFERENCE',
+        'COPY_ALERT_MESSAGE',
+        'ITEM_ON_HOLDS_SHELF',
+        'STAFF_C',
+        'STAFF_CH',
+        'STAFF_CHR',
+        'STAFF_CR',
+        'STAFF_H',
+        'STAFF_HR',
+        'STAFF_R'
     ]
 
-    // Default to checked for "Automatically override for subsequent items?"
-    service.default_auto_override = [
+    // after the first override of any of these events, 
+    // auto-override them in subsequent calls.
+    service.checkout_auto_override_after_first = [
         'PATRON_EXCEEDS_OVERDUE_COUNT',
         'PATRON_BARRED',
         'PATRON_EXCEEDS_LOST_COUNT',
@@ -73,6 +85,34 @@ function($uibModal , $q , egCore , egAlertDialog , egConfirmDialog,  egAddCopyAl
         'PATRON_EXCEEDS_LONGOVERDUE_COUNT'
     ]
 
+
+    // overridable during renewal
+    service.renew_overridable_events = [
+        'PATRON_EXCEEDS_OVERDUE_COUNT',
+        'PATRON_EXCEEDS_LOST_COUNT',
+        'PATRON_EXCEEDS_CHECKOUT_COUNT',
+        'PATRON_EXCEEDS_FINES',
+        'PATRON_EXCEEDS_LONGOVERDUE_COUNT',
+        'CIRC_EXCEEDS_COPY_RANGE',
+        'ITEM_DEPOSIT_REQUIRED',
+        'ITEM_RENTAL_FEE_REQUIRED',
+        'ITEM_DEPOSIT_PAID',
+        'COPY_CIRC_NOT_ALLOWED',
+        'COPY_NOT_AVAILABLE',
+        'COPY_IS_REFERENCE',
+        'COPY_ALERT_MESSAGE',
+        'COPY_NEEDED_FOR_HOLD',
+        'MAX_RENEWALS_REACHED',
+        'CIRC_CLAIMS_RETURNED',
+        'STAFF_C',
+        'STAFF_CH',
+        'STAFF_CHR',
+        'STAFF_CR',
+        'STAFF_H',
+        'STAFF_HR',
+        'STAFF_R'
+    ];
+
     // these checkin events do not produce alerts when 
     // options.suppress_alerts is in effect.
     service.checkin_suppress_overrides = [
@@ -359,7 +399,7 @@ function($uibModal , $q , egCore , egAlertDialog , egConfirmDialog,  egAddCopyAl
 
         } 
 
-        if (evt.filter(function(e){return !service.auto_override_circ_events[e.textcode];}).length == 0) {
+        if (evt.filter(function(e){return !service.auto_override_checkout_events[e.textcode];}).length == 0) {
             // user has already opted to override these type
             // of events.  Re-run the checkout w/ override.
             options.override = true;
@@ -392,7 +432,7 @@ function($uibModal , $q , egCore , egAlertDialog , egConfirmDialog,  egAddCopyAl
         } 
 
         // renewal auto-overrides are the same as checkout
-        if (evt.filter(function(e){return !service.auto_override_circ_events[e.textcode];}).length == 0) {
+        if (evt.filter(function(e){return !service.auto_override_checkout_events[e.textcode];}).length == 0) {
             // user has already opted to override these type
             // of events.  Re-run the renew w/ override.
             options.override = true;
@@ -452,30 +492,26 @@ function($uibModal , $q , egCore , egAlertDialog , egConfirmDialog,  egAddCopyAl
         // track the barcode regardless of whether it refers to a copy
         angular.forEach(evt, function(e){ e.copy_barcode = params.copy_barcode; });
 
-        // test for success first to simplify things
-        if (evt[0].textcode == 'SUCCESS') {
-            egCore.audio.play('info.renew');
-            return $q.when(final_resp);
-        }
-
-        // handle Overridable and Non-Overridable Events, but only if no skipped non-overridable events
-        if (evt.filter(function(e){return service.auto_skip_circ_events[e.textcode];}).length == 0) {
+        // Overridable Events
+        if (evt.filter(function(e){return service.renew_overridable_events.indexOf(e.textcode) > -1;}).length > 0)
             return service.handle_overridable_renew_event(evt, params, options);
-        }
 
         // Other events
         switch (evt[0].textcode) {
+            case 'SUCCESS':
+                egCore.audio.play('info.renew');
+                return $q.when(final_resp);
+
             case 'COPY_IN_TRANSIT':
             case 'PATRON_CARD_INACTIVE':
             case 'PATRON_INACTIVE':
             case 'PATRON_ACCOUNT_EXPIRED':
             case 'CIRC_CLAIMS_RETURNED':
-            case 'ITEM_NOT_CATALOGED':
-            case 'ASSET_COPY_NOT_FOUND':
-                // since handle_overridable_renew_event essentially advertises these events at some point,
-                // we no longer need the original alerts; however, the sound effects are still nice.
                 egCore.audio.play('warning.renew');
-                return $q.reject();
+                return service.exit_alert(
+                    egCore.strings[evt[0].textcode],
+                    {barcode : params.copy_barcode}
+                );
 
             default:
                 egCore.audio.play('warning.renew.unknown');
@@ -497,14 +533,16 @@ function($uibModal , $q , egCore , egAlertDialog , egConfirmDialog,  egAddCopyAl
         // track the barcode regardless of whether it refers to a copy
         angular.forEach(evt, function(e){ e.copy_barcode = params.copy_barcode; });
 
-        // test for success first to simplify things
-        if (evt[0].textcode == 'SUCCESS') {
-            egCore.audio.play('success.checkout');
-            return $q.when(final_resp);
-        }
+        // Overridable Events
+        if (evt.filter(function(e){return service.checkout_overridable_events.indexOf(e.textcode) > -1;}).length > 0)
+            return service.handle_overridable_checkout_event(evt, params, options);
 
-        // other events that should precede generic overridable/non-overridable handling
+        // Other events
         switch (evt[0].textcode) {
+            case 'SUCCESS':
+                egCore.audio.play('success.checkout');
+                return $q.when(final_resp);
+
             case 'ITEM_NOT_CATALOGED':
                 egCore.audio.play('error.checkout.no_cataloged');
                 return service.precat_dialog(params, options);
@@ -517,25 +555,16 @@ function($uibModal , $q , egCore , egAlertDialog , egConfirmDialog,  egAddCopyAl
             case 'COPY_IN_TRANSIT':
                 egCore.audio.play('warning.checkout.in_transit');
                 return service.copy_in_transit_dialog(evt, params, options);
-        }
-
-        // handle Overridable and Non-Overridable Events, but only if no skipped non-overridable events
-        if (evt.filter(function(e){return service.auto_skip_circ_events[e.textcode];}).length == 0) {
-            return service.handle_overridable_checkout_event(evt, params, options);
-        }
 
-        // Other events
-        switch (evt[0].textcode) {
             case 'PATRON_CARD_INACTIVE':
             case 'PATRON_INACTIVE':
             case 'PATRON_ACCOUNT_EXPIRED':
             case 'CIRC_CLAIMS_RETURNED':
-            case 'ITEM_NOT_CATALOGED':
-            case 'ASSET_COPY_NOT_FOUND':
-                // since handle_overridable_checkout_event essentially advertises these events at some point,
-                // we no longer need the original alerts; however, the sound effects are still nice.
                 egCore.audio.play('warning.checkout');
-                return $q.reject();
+                return service.exit_alert(
+                    egCore.strings[evt[0].textcode],
+                    {barcode : params.copy_barcode}
+                );
 
             default:
                 egCore.audio.play('error.checkout.unknown');
@@ -750,7 +779,6 @@ function($uibModal , $q , egCore , egAlertDialog , egConfirmDialog,  egAddCopyAl
                 ['$scope', '$uibModalInstance', 
                 function($scope, $uibModalInstance) {
                 $scope.events = evt;
-                $scope.action = action;
 
                 // Find the event, if any, that is for ITEM_ON_HOLDS_SHELF
                 //  and grab the patron name of the owner. 
@@ -769,77 +797,18 @@ function($uibModal , $q , egCore , egAlertDialog , egConfirmDialog,  egAddCopyAl
                     $scope.patronID = $scope.holdEvent.payload.patron_id;
                 }
 
+                $scope.auto_override =
+                    evt.filter(function(e){
+                        return service.checkout_auto_override_after_first.indexOf(evt.textcode) > -1;
+                    }).length > 0;
                 $scope.copy_barcode = params.copy_barcode; // may be null
 
                 // Implementation note: Why not use a primitive here? It
                 // doesn't work.  See: 
                 // http://stackoverflow.com/questions/18642371/checkbox-not-binding-to-scope-in-angularjs
-                $scope.formdata = {
-                    clearHold : service.clearHold,
-                    nonoverridable: evt.filter(function(e){
-                        return service.nonoverridable_events.indexOf(e.textcode) > -1;}).length > 0,
-                    event_ui_data : Object.fromEntries(
-                        evt.map( e => [ e.ilsevent, {
-                            // non-overridable events will be rare, but they are skippable.  We use
-                            // the same checkbox variable to track desired skip and auto-override
-                            // selections.
-                            overridable: service.nonoverridable_events.indexOf(e.textcode) == -1,
-                            // for non-overridable events, we'll default the checkbox to any previous
-                            // choice made for the current patron, though normally the UI will be
-                            // suppressed unless some previously unencountered events are in the set
-                            checkbox: service.nonoverridable_events.indexOf(e.textcode) > -1
-                            ? (service.auto_skip_circ_events[e.textcode] == undefined
-                                ? false
-                                : service.auto_skip_circ_events[e.textcode]
-                            )
-                            // if a given event is overridable, said checkbox will default to any previous
-                            // choice made for the current patron, as long as there are no non-overridable
-                            // events in the set (because we'll disable the checkbox in that case and don't
-                            // want to imply that we're going to set an auto-override)
-                            : (service.auto_override_circ_events[e.textcode] == undefined
-                                ? (
-                                    service.nonoverridable_events.indexOf(e.textcode) > -1
-                                    ? false
-                                    : service.default_auto_override.indexOf(e.textcode) > -1
-                                )
-                                : service.auto_override_circ_events[e.textcode]
-                            )
-                        }])
-                    ) 
-                };
-
-                function update_auto_override_and_skip_lists() {
-                    angular.forEach(evt, function(e){
-                        if ($scope.formdata.nonoverridable) {
-                            // the action had at least one non-overridable event, so let's only
-                            // record skip choices for those
-                            if (!$scope.formdata.event_ui_data[e.ilsevent].overridable) {
-                                if ($scope.formdata.event_ui_data[e.ilsevent].checkbox) {
-                                    // grow the skip list
-                                    service.auto_skip_circ_events[e.textcode] = true;
-                                } else {
-                                    // shrink the skip list
-                                    service.auto_skip_circ_events[e.textcode] = false;
-                                }
-                            }
-                        } else {
-                            // record all auto-override choices
-                            if ($scope.formdata.event_ui_data[e.ilsevent].checkbox) {
-                                // grow the auto-override list
-                                service.auto_override_circ_events[e.textcode] = true;
-                            } else {
-                                // shrink the auto-override list
-                                service.auto_override_circ_events[e.textcode] = false;
-                            }
-                        }
-                    });
-                    // for debugging
-                    window.oils_auto_skip_circ_events = service.auto_skip_circ_events;
-                    window.oils_auto_override_circ_events = service.auto_override_circ_events;
-                }
+                $scope.formdata = {clearHold : service.clearHold};
 
                 $scope.ok = function() { 
-                    update_auto_override_and_skip_lists();
                     // Handle the cancellation of the assciated hold here
                     if ($scope.formdata.clearHold && $scope.holdID) {
                         egCore.net.request(
@@ -853,14 +822,7 @@ function($uibModal , $q , egCore , egAlertDialog , egConfirmDialog,  egAddCopyAl
                     $uibModalInstance.close();
                 }
 
-                $scope.skip = function($event) {
-                    update_auto_override_and_skip_lists();
-                    $uibModalInstance.dismiss();
-                    $event.preventDefault();
-                }
-
                 $scope.cancel = function ($event) { 
-                    window.oils_cancel_batch = true;
                     $uibModalInstance.dismiss();
                     $event.preventDefault();
                 }
@@ -877,6 +839,12 @@ function($uibModal , $q , egCore , egAlertDialog , egConfirmDialog,  egAddCopyAl
                     return service.checkin(params, options);
                 }
 
+                // checkout/renew support override-after-first
+                angular.forEach(evt, function(e){
+                    if (service.checkout_auto_override_after_first.indexOf(e.textcode) > -1)
+                        service.auto_override_checkout_events[e.textcode] = true;
+                });
+
                 return service[action](params, options);
             }
         );
index 172e81d..5d06d71 100644 (file)
@@ -97,24 +97,8 @@ function($uibModal, $interpolate, $rootScope, $q, egAuth, egStrings, egNet, ngTo
 
             )['finally'](function() {
                 // always undo the operator change after a perm override.
-                // well, unless inside a UI "batch" like Renew All
-                if (!window.oils_inside_batch) {
-                    console.debug("clearing op-change after perm override redo");
-                    window.oils_op_change_within_batch = false;
-                    service.changeOperatorUndo(true);
-                } else {
-                    // up to the batch caller to call changeOperatorUndo
-                    console.debug("persisting op-change after perm override redo");
-                    window.oils_op_change_within_batch = true;
-                    // this is an even kludgier use of window-scoped variables
-                    window.oils_op_change_undo_func = function() {
-                        console.debug("clearing op-change after perm override redo");
-                        service.changeOperatorUndo(true);
-                    }
-                    window.oils_op_change_toast_func = function() {
-                        ngToast.create(egStrings.PERM_OP_CHANGE_PERSIST);
-                    }
-                }
+                console.debug("clearing op-change after perm override redo");
+                service.changeOperatorUndo(true);
             });
         });
     }
diff --git a/docs/RELEASE_NOTES_NEXT/Circulation/override-dialogs.adoc b/docs/RELEASE_NOTES_NEXT/Circulation/override-dialogs.adoc
deleted file mode 100644 (file)
index 0e13967..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-== Override Dialogs  ==
-
-This reworks the override action dialogs in the patron display for Check Out and Items Out, and in the Circulation -> Renew Items interface.  It exposes the auto-override behavior as checkboxes giving staff more fine grained control over which events are auto-forced or skipped upon subsequent encounters.  It also changes the Cancel action for batch renewals to abort the remaining renewals in the batch, and makes it so that new authorization credentials provided during such a batch will be treated as an operator change for the entire batch.  We also fix an existing bug where events marked as already encountered for auto-override could leak into other patron contexts via Patron Search.