diff --git a/client/src/i18n/en/barcode.json b/client/src/i18n/en/barcode.json index e22309cf6b..ee4ad62513 100644 --- a/client/src/i18n/en/barcode.json +++ b/client/src/i18n/en/barcode.json @@ -1,5 +1,11 @@ -{"BARCODE":{"SCAN":"Scan Invoice Barcode", -"AWAITING_INPUT":"Waiting for Input", -"AWAITING_HTTP":"Barcode Read! Looking up Invoice...", -"READ_SUCCESS":"Found Invoice", -"READ_ERROR":"Unreadable Barcode! Please enter the barcode manually."}} \ No newline at end of file +{ + "BARCODE" : { + "SCAN" : "Scan Document Barcode", + "AWAITING_INPUT" : "Waiting for Input", + "AWAITING_HTTP" : "Barcode Read! Looking up Record...", + "READ_SUCCESS" : "Found Record", + "READ_ERROR" : "Unreadable Barcode! Please enter the barcode manually.", + "LOST_FOCUS" : "The barcode input has lost focus. Please click \"Read Barcode\" to ready the barcode component.", + "RESET_BUTTON" : "Read Barcode" + } +} diff --git a/client/src/i18n/fr/barcode.json b/client/src/i18n/fr/barcode.json index b5aa15d6e7..59a9060650 100644 --- a/client/src/i18n/fr/barcode.json +++ b/client/src/i18n/fr/barcode.json @@ -1,5 +1,11 @@ -{"BARCODE":{"SCAN":"Scanner le Code à Barres", -"AWAITING_INPUT":"En Attente d'Entrée", -"AWAITING_HTTP":"Code à barres lu! Recherche de factures ....", -"READ_SUCCESS":"Facture Trouvée", -"READ_ERROR":"Code à barres illisible! Entrez le code à barres manuellement."}} \ No newline at end of file +{ + "BARCODE" : { + "SCAN" : "Scanner le Code à Barres", + "AWAITING_INPUT" : "En Attente d'Entrée", + "AWAITING_HTTP" : "Code à barres lu! Recherche l'enregistrement....", + "READ_SUCCESS" : "Trouvée", + "READ_ERROR" : "Code à barres illisible! Entrez le code à barres manuellement.", + "LOST_FOCUS" : "L'entrée du code à barres a perdu le focus. Veuillez cliquer sur \"Lire le code à barres\" pour préparer le composant de code à barres.", + "RESET_BUTTON" : "Lire le code à barres" + } +} diff --git a/client/src/js/components/bhBarcodeScanner.js b/client/src/js/components/bhBarcodeScanner.js new file mode 100644 index 0000000000..629ed65c29 --- /dev/null +++ b/client/src/js/components/bhBarcodeScanner.js @@ -0,0 +1,69 @@ +angular.module('bhima.components') + .component('bhBarcodeScanner', { + templateUrl : '/modules/templates/bhBarcodeScanner.html', + controller : bhBarcodeScanner, + bindings : { + onScanCallback : '&', + }, + }); + +bhBarcodeScanner.$inject = [ + '$timeout', '$window', 'BarcodeService', +]; + +function bhBarcodeScanner($timeout, $window, Barcode) { + const $ctrl = this; + + // steps in the search space + const steps = { + AWAIT_READ : 2, + AWAIT_HTTP : 4, + READ_SUCCESS : 8, + READ_ERROR : 16, + LOST_FOCUS : 32, + }; + + $ctrl.$onInit = () => { + angular.extend($ctrl, { steps }); + $ctrl.currentStep = steps.AWAIT_READ; + $ctrl.setFocusOnHiddenInput(); + }; + + const setFocusOnHiddenInput = () => { + // clear previous values + delete $ctrl.barcode; + + // find and focus the input + const input = $window.document.getElementById('hidden-barcode-input'); + input.focus(); + + // set view state correctly + $ctrl.isResetButtonVisible = false; + $ctrl.currentStep = steps.AWAIT_READ; + }; + + // wrap setFocusOnHiddenInput() in $timeout to trigger $digest + $ctrl.setFocusOnHiddenInput = () => { + $timeout(setFocusOnHiddenInput); + }; + + $ctrl.triggerBarcodeRead = () => { + $ctrl.currentStep = steps.AWAIT_HTTP; + + Barcode.search($ctrl.barcode) + .then(record => { + $ctrl.currentStep = steps.READ_SUCCESS; + $ctrl.record = record; + $ctrl.onScanCallback({ record }); + }) + .catch(() => { + $ctrl.currentStep = steps.READ_ERROR; + $ctrl.isResetButtonVisible = true; + }); + }; + + $ctrl.showResetButton = () => { + $ctrl.isResetButtonVisible = true; + $ctrl.currentStep = steps.LOST_FOCUS; + }; +} diff --git a/client/src/js/services/BarcodeService.js b/client/src/js/services/BarcodeService.js index 7df56cd7cd..f0580217f5 100644 --- a/client/src/js/services/BarcodeService.js +++ b/client/src/js/services/BarcodeService.js @@ -1,10 +1,10 @@ angular.module('bhima.services') .service('BarcodeService', BarcodeService); -BarcodeService.$inject = [ '$http', 'util' ]; +BarcodeService.$inject = ['$http', 'util']; function BarcodeService($http, util) { - var service = this; + const service = this; // TODO - barcode redirection service.redirect = angular.noop; diff --git a/client/src/modules/cash/cash-form.service.js b/client/src/modules/cash/cash-form.service.js index 5f3c029eed..08cf3cd59b 100644 --- a/client/src/modules/cash/cash-form.service.js +++ b/client/src/modules/cash/cash-form.service.js @@ -121,7 +121,7 @@ function CashFormService(AppCache, Session, Patients, Exchange) { CashForm.prototype.configure = function configure(config) { if (config.patient) { - this.setPatient(config.invoices); + this.setPatient(config.patient); } if (config.description) { diff --git a/client/src/modules/cash/modals/barcode-scanner-modal.ctrl.js b/client/src/modules/cash/modals/barcode-scanner-modal.ctrl.js index 7ad5133191..051da5cb0e 100644 --- a/client/src/modules/cash/modals/barcode-scanner-modal.ctrl.js +++ b/client/src/modules/cash/modals/barcode-scanner-modal.ctrl.js @@ -2,8 +2,8 @@ angular.module('bhima.controllers') .controller('CashBarcodeScannerModalController', CashBarController); CashBarController.$inject = [ - '$state', 'CashboxService', 'NotifyService', 'BarcodeService', 'PatientService', - 'bhConstants', '$uibModalInstance', '$timeout', 'PatientInvoiceService', '$rootScope' + '$state', 'CashboxService', 'NotifyService', 'PatientService', + 'bhConstants', '$uibModalInstance', '$timeout', 'PatientInvoiceService', '$rootScope', ]; /** @@ -13,102 +13,48 @@ CashBarController.$inject = [ * This controller is responsible for scanning barcodes and the * configuring the CashForm with the barcode */ -function CashBarController($state, Cashboxes, Notify, Barcodes, Patients, bhConstants, Instance, $timeout, Invoices, RS) { - var vm = this; - var id = $state.params.id; +function CashBarController($state, Cashboxes, Notify, Patients, bhConstants, Instance, $timeout, Invoices, RS) { + const vm = this; + const { id } = $state.params; - var MODAL_CLOSE_TIMEOUT = 0; + const MODAL_CLOSE_TIMEOUT = 0; - vm.triggerBarcodeRead = triggerBarcodeRead; - vm.dismiss = dismiss; + vm.dismiss = () => Instance.dismiss(); - vm.loading = true; - - vm.INITIALIZED = 'initialized'; - vm.LOADING = 'loading'; - vm.READ_ERROR = 'read-error'; - vm.READ_SUCCESS = 'found'; - - // the first step is initialized - vm.step = vm.INITIALIZED; - - // determine if the input was a valid barcode - function isValidBarcode(input) { - return input.length >= bhConstants.barcodes.LENGTH; - } - - function dismiss() { - Instance.dismiss(); - } - - // TODO(@jniles) potentially this should tell you if you are trying to read a - // cash payment instead of an invoice - // TODO(@jniles) potentially this should clear the input when the barcode - // is greater in length than 10. - // TODO(@jniles) this should be a component - function triggerBarcodeRead() { - if (isValidBarcode(vm.barcode)) { - searchForBarcode(vm.barcode); - } else { - vm.step = vm.READ_ERROR; - } - } + vm.onScanCallback = onScanCallback; // send an HTTP request based on the barcode to get the invoice in question, // then load the patient information in the background - function searchForBarcode(barcode) { - - // set the loading step - vm.step = vm.LOADING; + function onScanCallback(invoice) { + let invoiceBalance; - Barcodes.search(barcode) - .then(function (invoice) { - vm.invoice = invoice; - return Invoices.balance(invoice.uuid); + return Invoices.balance(invoice.uuid) + .then(balance => { + invoiceBalance = balance; + return Patients.read(null, { debtor_uuid : invoice.debtor_uuid }); }) - .then(function (balance) { - vm.balance = balance; - return Patients.read(null, { debtor_uuid : vm.invoice.debtor_uuid }); - }) - .then(function (patients) { - - // de-structure search array - var patient = patients[0]; - - vm.patient = patient; + .then(patients => { + const [patient] = patients; - // emit the + // emit the configuration event RS.$broadcast('cash:configure', { - invoices: [vm.balance], - patient: vm.patient, - description : vm.invoice.serviceName + patient, + invoices : [invoiceBalance], + description : invoice.serviceName, }); - vm.step = vm.READ_SUCCESS; - // close the modal after a timeout - $timeout(function () { + $timeout(() => { Instance.close(); }, MODAL_CLOSE_TIMEOUT, false); }) - .catch(function (error) { - vm.step = vm.READ_ERROR; - }) - .finally(function () { - toggleFlickerAnimation(); - }); - } - - function toggleFlickerAnimation() { - vm.flicker = !vm.flicker; + .catch(Notify.handleError); } // fired on state startup function startup() { - vm.flicker = true; - Cashboxes.read(id) - .then(function (cashbox) { + .then(cashbox => { vm.cashbox = cashbox; }) .catch(Notify.handleError); diff --git a/client/src/modules/cash/modals/barcode-scanner-modal.html b/client/src/modules/cash/modals/barcode-scanner-modal.html index a493ceccbd..6ab05df615 100644 --- a/client/src/modules/cash/modals/barcode-scanner-modal.html +++ b/client/src/modules/cash/modals/barcode-scanner-modal.html @@ -1,5 +1,4 @@
-
diff --git a/client/src/modules/templates/bhBarcodeScanner.html b/client/src/modules/templates/bhBarcodeScanner.html new file mode 100644 index 0000000000..c5ce77ced3 --- /dev/null +++ b/client/src/modules/templates/bhBarcodeScanner.html @@ -0,0 +1,37 @@ +
+ + +

+ +

+ + BARCODE.LOST_FOCUS + + + BARCODE.AWAITING_INPUT + + + + + BARCODE.AWAITING_HTTP + + + + BARCODE.READ_SUCCESS {{ $ctrl.record.reference }} + + + + BARCODE.READ_ERROR + +

+ + +
+ +
+ + + +