LP#1706147: handle multiple matches on patron barcode completion in web client user/cesardv/jeffdavis_lp1721610-user-barcode-completion
authorJeff Davis <jdavis@sitka.bclibraries.ca>
Fri, 6 Oct 2017 18:15:05 +0000 (11:15 -0700)
committerCesar Velez <cesar.velez@equinoxinitiative.org>
Wed, 18 Oct 2017 14:05:22 +0000 (10:05 -0400)
Signed-off-by: Jeff Davis <jdavis@sitka.bclibraries.ca>
Signed-off-by: Cesar Velez <cesar.velez@equinoxinitiative.org>
Open-ILS/web/js/ui/default/staff/circ/patron/app.js

index 4d4c728..d3b5653 100644 (file)
@@ -421,8 +421,8 @@ function($scope,  $q , $location , $filter , egCore , egNet , egUser , egAlertDi
 }])
 
 .controller('PatronBarcodeSearchCtrl',
-       ['$scope','$location','egCore','egConfirmDialog','egUser','patronSvc',
-function($scope , $location , egCore , egConfirmDialog , egUser , patronSvc) {
+       ['$scope','$location','egCore','egConfirmDialog','egUser','patronSvc','$uibModal','$q',
+function($scope , $location , egCore , egConfirmDialog , egUser , patronSvc , $uibModal , $q) {
     $scope.selectMe = true; // focus text input
     patronSvc.clearPrimary(); // clear the default user
 
@@ -457,72 +457,127 @@ function($scope , $location , egCore , egConfirmDialog , egUser , patronSvc) {
 
         var user_id;
 
-        // lookup barcode
-        egCore.net.request(
-            'open-ils.actor',
-            'open-ils.actor.get_barcodes',
-            egCore.auth.token(), egCore.auth.user().ws_ou(), 
-            'actor', args.barcode)
+        // given a scanned barcode, this function finds any matching users
+        // and handles multiple matches due to barcode completion
+        function handleBarcodeCompletion(scanned_barcode) {
+            var deferred = $q.defer();
 
-        .then(function(resp) { // get_barcodes
+            egCore.net.request(
+                'open-ils.actor',
+                'open-ils.actor.get_barcodes',
+                egCore.auth.token(), egCore.auth.user().ws_ou(), 
+                'actor', scanned_barcode)
 
-            if (evt = egCore.evt.parse(resp)) {
-                alert(evt); // FIXME
-                return;
-            }
+            .then(function(resp) { // get_barcodes
 
-            if (!resp || !resp[0]) {
-                $scope.bcNotFound = args.barcode;
-                $scope.selectMe = true;
-                egCore.audio.play('warning.patron.not_found');
-                return;
-            }
+                if (evt = egCore.evt.parse(resp)) {
+                    alert(evt); // FIXME
+                    deferred.reject();
+                    return;
+                }
+
+                if (!resp || !resp[0]) {
+                    $scope.bcNotFound = args.barcode;
+                    $scope.selectMe = true;
+                    egCore.audio.play('warning.patron.not_found');
+                    deferred.reject();
+                    return;
+                }
+
+                if (resp.length == 1) {
+                    // exactly one matching barcode: return it
+                    deferred.resolve();
+                    user_id = resp[0].id;
+                } else {
+                    // multiple matching barcodes: let the user pick one 
+                    var barcode_map = {};
+                    var matches = [];
+                    var promises = [];
+                    var selected_barcode;
+                    angular.forEach(resp, function(match) {
+                        promises.push(
+                            egUser.get(match.id, {useFields : ['home_ou']}).then(function(user) {
+                                barcode_map[match.barcode] = user.id();
+                                matches.push( {
+                                    barcode: match.barcode,
+                                    title: user.first_given_name() + ' ' + user.family_name(),
+                                    org_name: user.home_ou().name(),
+                                    org_shortname: user.home_ou().shortname()
+                                });
+                            })
+                        );
+                    });
+                    return $q.all(promises)
+                    .then(function() {
+                        $uibModal.open({
+                            templateUrl: './circ/share/t_barcode_choice_dialog',
+                            controller:
+                                ['$scope', '$uibModalInstance',
+                                function($scope, $uibModalInstance) {
+                                $scope.matches = matches;
+                                $scope.ok = function(barcode) {
+                                    $uibModalInstance.close();
+                                    selected_barcode = barcode;
+                                }
+                                $scope.cancel = function() {$uibModalInstance.dismiss()}
+                            }],
+                        }).result.then(function() {
+                            deferred.resolve();
+                            user_id = barcode_map[selected_barcode];
+                        });
+                    });
+                }
+            });
+            return deferred.promise;
+        }
+
+        // call our function to lookup matching users for the scanned barcode
+        handleBarcodeCompletion(args.barcode).then(function() {
 
             // see if an opt-in request is needed
-            user_id = resp[0].id;
             return egCore.net.request(
                 'open-ils.actor',
                 'open-ils.actor.user.org_unit_opt_in.check',
-                egCore.auth.token(), user_id);
-
-        }).then(function(optInResp) { // opt_in_check
+                egCore.auth.token(), user_id
+            ).then(function(optInResp) { // opt_in_check
 
-            if (evt = egCore.evt.parse(optInResp)) {
-                alert(evt); // FIXME
-                return;
-            }
+                if (evt = egCore.evt.parse(optInResp)) {
+                    alert(evt); // FIXME
+                    return;
+                }
 
-            if (optInResp == 2) {
-                // opt-in disallowed at this location by patron's home library
-                $scope.optInRestricted = true;
-                $scope.selectMe = true;
-                egCore.audio.play('warning.patron.opt_in_restricted');
-                return;
-            }
-           
-            if (optInResp == 1) {
-                // opt-in handled or not needed
-                return loadPatron(user_id);
-            }
+                if (optInResp == 2) {
+                    // opt-in disallowed at this location by patron's home library
+                    $scope.optInRestricted = true;
+                    $scope.selectMe = true;
+                    egCore.audio.play('warning.patron.opt_in_restricted');
+                    return;
+                }
+            
+                if (optInResp == 1) {
+                    // opt-in handled or not needed
+                    return loadPatron(user_id);
+                }
 
-            // opt-in needed, show the opt-in dialog
-            egUser.get(user_id, {useFields : []})
+                // opt-in needed, show the opt-in dialog
+                egUser.get(user_id, {useFields : []})
 
-            .then(function(user) { // retrieve user
-                var org = egCore.org.get(user.home_ou());
-                egConfirmDialog.open(
-                    egCore.strings.OPT_IN_DIALOG_TITLE,
-                    egCore.strings.OPT_IN_DIALOG,
-                    {   family_name : user.family_name(),
-                        first_given_name : user.first_given_name(),
-                        org_name : org.name(),
-                        org_shortname : org.shortname(),
-                        ok : function() { createOptIn(user.id()) },
-                        cancel : function() {}
-                    }
-                );
+                .then(function(user) { // retrieve user
+                    var org = egCore.org.get(user.home_ou());
+                    egConfirmDialog.open(
+                        egCore.strings.OPT_IN_DIALOG_TITLE,
+                        egCore.strings.OPT_IN_DIALOG,
+                        {   family_name : user.family_name(),
+                            first_given_name : user.first_given_name(),
+                            org_name : org.name(),
+                            org_shortname : org.shortname(),
+                            ok : function() { createOptIn(user.id()) },
+                            cancel : function() {}
+                        }
+                    );
+                })
             })
-        });
+        })
     }
 }])