From 3bd2fc13958e0dd249d41cf0ad626fb95b9af455 Mon Sep 17 00:00:00 2001 From: "afiq.hamzah" Date: Thu, 23 Feb 2023 14:08:42 +0800 Subject: [PATCH] Update MyKad reader implementation - prevent teller from overriding name, religion, address, and other sensitive fields if using MyKad reader - add support for Google Chrome browser ver. 64 backward compatible with branches PC - enhance error message handling when scanning if there is no card reader connected, no card is inserted in card reader, and if card reader is entered incorrectly --- public/js/mykad-reader-customer.js | 95 ++++++-- resources/views/customers/index.blade.php | 278 +++++++++++++++++++++- 2 files changed, 352 insertions(+), 21 deletions(-) diff --git a/public/js/mykad-reader-customer.js b/public/js/mykad-reader-customer.js index 4c7efb5..caca8e5 100644 --- a/public/js/mykad-reader-customer.js +++ b/public/js/mykad-reader-customer.js @@ -1,7 +1,6 @@ - let button_read_mykad = document.getElementById("button_read_mykad"); -let button_close_modal = document.querySelector("#daftar_pelanggan button.btn.btn-danger"); +let button_close_modal = document.querySelector("#daftar_pelanggan_mykad_reader button.btn.btn-danger"); let original_photo_loader = document.querySelector("#photo-mykad").src; let showLoader = () => { @@ -25,10 +24,21 @@ let original_photo_loader = document.querySelector("#photo-mykad").src; function callbackDoneGetListCardReader(data, respcode) { console.log('done get list card reader'); + if(respcode === -1){ console.log({'location': 'callbackDoneGetListCardReader', 'data' : data} ); } + let isDevicesConnected = Object.keys(data).length > 0; + + if(! isDevicesConnected){ + hideLoader(); + + Swal.fire({ icon: 'error', title: 'Pembaca MyKad tidak dapat dikesan, sila periksa sambungan', }); + + return; + } + let slots = data.toString().split(','); WebSocketManager.open(doneOpenReaderConnection, slots[0]); } @@ -38,18 +48,44 @@ let original_photo_loader = document.querySelector("#photo-mykad").src; WebSocketManager.readAllText(callBackAfterReadMykad); } + function handleMyKadReaderError(sw12AndApiName) + { + hideLoader(); + + let error_handler_dictionary = { + '0x80100069' : 'Tiada MyKad dikesan, sila masukkan Mykad untuk dibaca', + '0x80100066' : 'MyKad mungkin dimasukkan terbalik, sila masukkan dengan betul', + 'default' : sw12AndApiName, + }; + + let error_data = sw12AndApiName.split(" "); + + let error_code = error_data.filter(x => x.startsWith('0x')).splice(-1) + + let error_message = error_handler_dictionary['default']; + + let hasDefinedError = error_handler_dictionary.hasOwnProperty(error_code); + + if(hasDefinedError){ + error_message = error_handler_dictionary[error_code]; + } + + Swal.fire({ icon: 'error', title: error_message, }); + } + function callBackAfterReadMykad(data, respcode, sw12AndApiName) { if(respcode !== 0){ - hideLoader(); - Swal.fire({icon: 'error', title: sw12AndApiName,}); - return; + handleMyKadReaderError(sw12AndApiName); + return } checkIfMyKadExists(data.IDNum) - .then(response => response[0]) .then(response => { - if (response === 'no-data') { + let isResponseArray = Array.isArray(response); + resolved_response = isResponseArray ? response.pop() : response; + + if (resolved_response === 'no-data') { populateDaftarPelangganModal(data, handleReadPhoto); } else { let input_search_noic = document.getElementById("noic"); @@ -70,16 +106,28 @@ let original_photo_loader = document.querySelector("#photo-mykad").src; hideLoader(); } - function checkIfMyKadExists(myKadNumber){ + function checkIfMyKadExists(myKadNumber) { let myKadNumberWithoutHyphens = myKadNumber.replace(/-/g, ''); const url = wakil_caricustomer_endpoint + '/?icno=' + myKadNumberWithoutHyphens; - return fetch(url).then((response) => response.json()); + + const connectionConfig = { + headers: { + "Content-Type": "application/json", + "Accept": "application/json", + "X-Requested-With": "XMLHttpRequest", + "X-CSRF-Token": document.querySelector('input[name="_token"]').value + }, + credentials: "same-origin", + }; + + return fetch(url, connectionConfig) + .then(response => response.json()) } let populateDaftarPelangganModal = (data, callbackAfterPopulateDaftarPelanggan) => { - $('#daftar_pelanggan').modal('show'); - let modal_form = document.querySelector(".modal-body .row.form-group"); + $('#daftar_pelanggan_mykad_reader').modal('show'); + let modal_form = document.querySelector("#daftar_pelanggan_mykad_reader .modal-body .row.form-group"); const religions = [ ['01', 'Islam'], @@ -146,7 +194,16 @@ let original_photo_loader = document.querySelector("#photo-mykad").src; return isBumiputera; }; - let photo_container = document.getElementById("photo-mykad-container"); + let disablePointerEventsOnClickableInputs = () => { + modal_form.querySelector("input[name='bumiputera']").style.pointerEvents = 'none'; + modal_form.querySelector("input[name='warganegara']").style.pointerEvents = 'none'; + + modal_form.querySelector("select[name='bangsa']").style.pointerEvents = 'none'; + modal_form.querySelector("select[name='agama']").style.pointerEvents = 'none'; + } + + let mykad_modal = document.querySelector("#daftar_pelanggan_mykad_reader"); + let photo_container = mykad_modal.querySelector("#photo-mykad-container"); modal_form.querySelector("input[name='name']").value = data.OrgName; modal_form.querySelector("input[name='noic']").value = getMyKadNumberWithoutHypens(data.IDNum); @@ -158,11 +215,11 @@ let original_photo_loader = document.querySelector("#photo-mykad").src; modal_form.querySelector("select[name='agama']").value = getCodeFromValue(data.Religion, religions); modal_form.querySelector("textarea[name='alamat']").value = [data.Address1, data.Address2, data.Address3].join(", "); - let getPostCode = (postCodeCity) => postCodeCity.replace(/\D/g, ''); + let getPostCode = (postCodeCity) => postCodeCity.replace(/\D/g, ''); modal_form.querySelector("input[name='poskod']").value = getPostCode(data.PostcodeCity); - let getCityName = (postCodeCity) => postCodeCity.replace(/\d/g, ''); - modal_form.querySelector("input[name='daerah']").value = getCityName(data.PostcodeCity); + let getCityName = (postCodeCity) => postCodeCity.replace(/\d/g, ''); + modal_form.querySelector("input[name='daerah']").value = getCityName(data.PostcodeCity).trim(); modal_form.querySelector("input[name='negeri']").value = data.State; modal_form.querySelector("input[name='age']").value = getAgeFromDateOfBirth(data.BirthDate); @@ -173,9 +230,10 @@ let original_photo_loader = document.querySelector("#photo-mykad").src; photo_container.classList.remove('d-none'); photo_container.classList.add('d-flex'); - $('#daftar_pelanggan').modal('show'); + $('#daftar_pelanggan_mykad_reader').modal('show'); + disablePointerEventsOnClickableInputs(); callbackAfterPopulateDaftarPelanggan(); } @@ -203,9 +261,10 @@ function doneOpenReaderConnection2() function callbackAfterReadPhoto2(data, RespCode, RespSW12AndApiName) { - let photo = document.getElementById("photo-mykad"); + let mykad_modal = document.querySelector("#daftar_pelanggan_mykad_reader"); + let photo = mykad_modal.querySelector("#photo-mykad"); - let isDataEmpty = data + let isDataEmpty = data && Object.keys(data).length === 0 && Object.getPrototypeOf(data) === Object.prototype; diff --git a/resources/views/customers/index.blade.php b/resources/views/customers/index.blade.php index ed6e8c6..1bd7bb7 100644 --- a/resources/views/customers/index.blade.php +++ b/resources/views/customers/index.blade.php @@ -37,7 +37,7 @@ - Baca MyKad + Baca MyKad @@ -181,6 +181,140 @@ + + + + + +