diff --git a/.env.example b/.env.example index 1e819c27..e7821ee4 100644 --- a/.env.example +++ b/.env.example @@ -46,5 +46,5 @@ AWS_BUCKET= MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" -MYKAD_READER_PORT=8085 +MYKAD_READER_PORT=17321 MYKAD_READER_ENABLED_CAWANGAN='' # IF NO CAWANGAN STATED, ALL CAWANGAN IS ENABLED diff --git a/.env.staging b/.env.staging index 0be6b95c..91b447ec 100644 --- a/.env.staging +++ b/.env.staging @@ -3,14 +3,14 @@ APP_ENV=staging APP_VERSION=v2.2-staging APP_KEY=base64:O1XZDqK4H6+3GdrODgCaLr2l+OoWvgVhYr0GJ1KizW8= APP_DEBUG=true -APP_URL=http://172.16.6.200:8091 +APP_URL=https://staging.erahn.com.my HTTP_PORT=8091 MYSQL_PUBLISH_PORT=3309 -API_URL=http://172.16.6.200:8090 -API_URL_KOOP=http://172.16.6.200:8090 -API_URL_PKB=http://172.16.6.200:8090 +API_URL=https://api-staging.erahn.com.my +API_URL_KOOP=https://api-staging.erahn.com.my +API_URL_PKB=https://api-staging.erahn.com.my API_ARRAHNBID=http://lelong.test/api/ LOG_CHANNEL=stack @@ -54,5 +54,5 @@ AWS_BUCKET= MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" -MYKAD_READER_PORT=8085 +MYKAD_READER_PORT=17321 MYKAD_READER_ENABLED_CAWANGAN='' # IF NO CAWANGAN STATED, ALL CAWANGAN IS ENABLED \ No newline at end of file diff --git a/app/Http/Middleware/TrustProxies.php b/app/Http/Middleware/TrustProxies.php index 14befceb..39816113 100644 --- a/app/Http/Middleware/TrustProxies.php +++ b/app/Http/Middleware/TrustProxies.php @@ -12,7 +12,7 @@ class TrustProxies extends Middleware * * @var array|string|null */ - protected $proxies; + protected $proxies = '*'; /** * The headers that should be used to detect proxies. diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index ee8ca5bc..539a3f28 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -23,6 +23,8 @@ class AppServiceProvider extends ServiceProvider */ public function boot() { - // + if (strpos((string) config('app.url'), 'https://') === 0) { + \Illuminate\Support\Facades\URL::forceScheme('https'); + } } } diff --git a/config/mykad-reader.php b/config/mykad-reader.php index e1dc6da9..21576946 100644 --- a/config/mykad-reader.php +++ b/config/mykad-reader.php @@ -1,7 +1,7 @@ 'http://localhost:' . $x . '/?MYKADJSON'; +$default_port = '17321'; +$getReaderEndpoint = fn($x) => 'http://localhost:' . $x . '/read'; return[ 'endpoint' => env('MYKAD_READER_ENDPOINT', $getReaderEndpoint(env('MYKAD_READER_PORT', $default_port))), diff --git a/docker/nginx/default.conf b/docker/nginx/default.conf index 47a18309..182f3243 100644 --- a/docker/nginx/default.conf +++ b/docker/nginx/default.conf @@ -9,6 +9,9 @@ server { client_max_body_size 50M; location / { + # Production Apache public/.htaccess 301-strips trailing slashes. + # Nginx ignores .htaccess, so without this /path/ 404s while /path works. + rewrite ^/(.*)/$ /$1 last; try_files $uri @php; } diff --git a/public/js/mykad-reader-customer.js b/public/js/mykad-reader-customer.js index 3c53b650..e15ccbcb 100644 --- a/public/js/mykad-reader-customer.js +++ b/public/js/mykad-reader-customer.js @@ -1,293 +1,371 @@ let button_read_mykad = document.getElementById("button_read_mykad"); let button_close_modal = document.querySelector("#daftar_pelanggan_mykad_reader button.btn.btn-danger"); -let original_photo_loader = document.querySelector("#photo-mykad").src; +let photo_mykad = document.querySelector("#photo-mykad"); +let original_photo_loader = photo_mykad ? photo_mykad.src : ""; - let showLoader = () => { - let pageLoader = document.getElementById('page_loader'); - pageLoader.removeAttribute('class'); - pageLoader.classList.add('loading'); - }; +const MYKAD_READER_TIMEOUT_MS = 45000; +const MYKAD_READER_DEFAULT_ENDPOINT = "http://localhost:17321/read"; - let hideLoader = () => { - let pageLoader = document.getElementById('page_loader'); - pageLoader.removeAttribute('class'); - }; - - function handleMyKadReader() - { - showLoader(); - WebSocketManager.init("wss://localhost:5963/mykadwebsocket"); - WebSocketManager.listReader(callbackDoneGetListCardReader); - } - - 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]); - } - - function doneOpenReaderConnection() - { - 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){ - handleMyKadReaderError(sw12AndApiName); - return - } - - checkIfMyKadExists(data.IDNum) - .then(response => { - 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"); - let form_search_noic = document.querySelector("form[name='frmsearch']"); - - let getMyKadNumberWithoutHypens = myKadNumber => myKadNumber.replace(/-/g, ''); - input_search_noic.value = getMyKadNumberWithoutHypens(data.IDNum); - form_search_noic.submit(); - } - }) - .catch(error => { - Swal.fire({ - icon: 'error', - title: error, - }); - }); - - hideLoader(); - } - - function checkIfMyKadExists(myKadNumber) { - let myKadNumberWithoutHyphens = myKadNumber.replace(/-/g, ''); - - const url = wakil_caricustomer_endpoint + '/?icno=' + myKadNumberWithoutHyphens; - - 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_mykad_reader').modal('show'); - let modal_form = document.querySelector("#daftar_pelanggan_mykad_reader .modal-body .row.form-group"); - - const religions = [ - ['01', 'Islam'], - ['02', 'Hindu'], - ['03', 'Buddha'], - ['04', 'Kristian'], - ['05', 'Lain-lain'], - ]; - - const races = [ - ['M', 'Melayu'], - ['C', 'Cina'], - ['I', 'India'], - ['L', 'Lain-lain'], - ]; - - let getCodeFromValue = (needle, haystack) => { - let title_cased_text = needle.split(' ') - .map(w => w[0].toUpperCase() + w.substring(1).toLowerCase()) - .join(' '); - - return haystack.filter(x => x[1] == title_cased_text)[0][0]; - }; - - let getMyKadNumberWithoutHypens = (IDNum) => { - return IDNum.replace(/-/g, ''); - } - - let getFormattedDateOfBirth = (date_of_birth) => { - - let date_of_birth_hyphenated = date_of_birth.replace(/(\d{4})(\d{2})(\d{2})/, "$1-$2-$3"); - - const [year, month, day] = date_of_birth_hyphenated.split('-'); - return day + '/' + month + '/' + year; - }; - - let getAgeFromDateOfBirth = (date_of_birth) => { - - let date_of_birth_hyphenated = date_of_birth.replace(/(\d{4})(\d{2})(\d{2})/, "$1-$2-$3"); - - const [birth_year, birth_month, birth_day] = date_of_birth_hyphenated.split('-'); - - let formatBirthMonth = (birth_month) => { - let newbirthMonth = birth_month < 9 ? birth_month[1] : birth_month; - return newbirthMonth; - }; - - const count_leap_year = countLeapYears(birth_year, formatBirthMonth(birth_month), birth_day) - 1; - - const start = new Date(date_of_birth_hyphenated), - end = new Date(), - diff = new Date(end - start), - days = ((diff / 1000 / 60 / 60 / 24) - count_leap_year) / 365; - - return parseInt(days); - }; - - let getBumiputeraStatus = (race) => { - - const non_bumiputera_ethnicity = ['INDIA', 'CINA']; - - let isBumiputera = !non_bumiputera_ethnicity.includes(race); - - return isBumiputera; - }; - - 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("textarea[name='name']").value = data.OrgName; - modal_form.querySelector("input[name='noic']").value = getMyKadNumberWithoutHypens(data.IDNum); - modal_form.querySelector("input[name='tarikh_lahir']").value = getFormattedDateOfBirth(data.BirthDate); - modal_form.querySelector("input[name='negeri_lahir']").value = data.BirthPlace; - modal_form.querySelector("input[name='jantina']").value = data.Gender == 'LELAKI' ? 'Lelaki' : 'Perempuan'; - modal_form.querySelector("input[name='warganegara']").checked = data.Citizenship === 'WARGANEGARA' ? true : false; - modal_form.querySelector("input[name='bumiputera']").checked = getBumiputeraStatus(data.Race); - 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, ''); - 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).trim(); - - modal_form.querySelector("input[name='negeri']").value = data.State; - modal_form.querySelector("input[name='age']").value = getAgeFromDateOfBirth(data.BirthDate); - modal_form.querySelector("select[name='bangsa']").value = getCodeFromValue(data.Race, races); - - calculatePassportAge(); - - photo_container.classList.remove('d-none'); - photo_container.classList.add('d-flex'); - - $('#daftar_pelanggan_mykad_reader').modal('show'); - - - disablePointerEventsOnClickableInputs(); - callbackAfterPopulateDaftarPelanggan(); -} - - -function handleReadPhoto() -{ - WebSocketManager.init("wss://localhost:5963/mykadwebsocket"); - WebSocketManager.listReader(callbackDoneGetListCardReader2); -} - -function callbackDoneGetListCardReader2(data, respcode) -{ - if(respcode === -1){ - console.log({'location': 'callbackDoneGetListCardReader', 'data' : data} ); - } - - let slots = data.toString().split(','); - WebSocketManager.open(doneOpenReaderConnection2, slots[0]); -} - -function doneOpenReaderConnection2() -{ - WebSocketManager.readPhoto(callbackAfterReadPhoto2); -} - -function callbackAfterReadPhoto2(data, RespCode, RespSW12AndApiName) -{ - let mykad_modal = document.querySelector("#daftar_pelanggan_mykad_reader"); - let photo = mykad_modal.querySelector("#photo-mykad"); - - let isDataEmpty = data - && Object.keys(data).length === 0 - && Object.getPrototypeOf(data) === Object.prototype; - - if(isDataEmpty){ - photo.src = original_photo_loader; +let showLoader = () => { + let pageLoader = document.getElementById('page_loader'); + if (!pageLoader) { return; } + pageLoader.removeAttribute('class'); + pageLoader.classList.add('loading'); +}; - photo.src = 'data:image/jpeg;base64, ' + data.Base64Photo; +let hideLoader = () => { + let pageLoader = document.getElementById('page_loader'); + if (!pageLoader) { + return; + } + pageLoader.removeAttribute('class'); +}; + +function getMyKadReaderEndpoint() { + let endpoint = (typeof mykad_reader_endpoint !== 'undefined' && mykad_reader_endpoint) + ? String(mykad_reader_endpoint).trim() + : ''; + + if (!endpoint || endpoint.includes('MYKADJSON') || endpoint.includes(':8085')) { + return MYKAD_READER_DEFAULT_ENDPOINT; + } + + return endpoint; } +async function parseJsonResponse(response) { + let text = await response.text(); + let trimmed = (text || '').trim(); + + if (!trimmed) { + throw new Error('Pembaca MyKad tidak memulangkan data. Sila cuba lagi.'); + } + + if (trimmed.charAt(0) === '<') { + throw new Error('Pembaca MyKad memulangkan halaman web, bukan data kad. Sila pastikan perkhidmatan mykad-helper sedang berjalan di localhost:17321.'); + } + + try { + return JSON.parse(trimmed); + } catch (error) { + throw new Error('Pembaca MyKad memulangkan data yang tidak sah. Sila cuba lagi.'); + } +} + +function getMyKadNumberWithoutHyphens(nric) { + return String(nric || '').replace(/-/g, ''); +} + +function titleCase(value) { + return String(value || '') + .toLowerCase() + .split(' ') + .filter(Boolean) + .map(word => word.charAt(0).toUpperCase() + word.slice(1)) + .join(' '); +} + +function getCodeFromValue(needle, haystack, fallback) { + let normalised = titleCase(needle); + let match = haystack.find(item => item[1].toLowerCase() === normalised.toLowerCase()); + + return match ? match[0] : fallback; +} + +function mapGender(gender) { + let value = String(gender || '').toLowerCase(); + + if (['male', 'lelaki', 'l', 'm'].includes(value)) { + return 'Lelaki'; + } + + if (['female', 'perempuan', 'p', 'f'].includes(value)) { + return 'Perempuan'; + } + + return gender || ''; +} + +function formatDateOfBirth(dob) { + if (!dob) { + return ''; + } + + let hyphenated = String(dob).includes('-') + ? String(dob) + : String(dob).replace(/(\d{4})(\d{2})(\d{2})/, '$1-$2-$3'); + + let [year, month, day] = hyphenated.split('-'); + + if (!year || !month || !day) { + return dob; + } + + return day + '/' + month + '/' + year; +} + +function getAgeFromDateOfBirth(dob) { + if (!dob) { + return ''; + } + + let hyphenated = String(dob).includes('-') + ? String(dob) + : String(dob).replace(/(\d{4})(\d{2})(\d{2})/, '$1-$2-$3'); + + let birthDate = new Date(hyphenated); + if (Number.isNaN(birthDate.getTime())) { + return ''; + } + + let today = new Date(); + let age = today.getFullYear() - birthDate.getFullYear(); + let monthDiff = today.getMonth() - birthDate.getMonth(); + + if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) { + age -= 1; + } + + return age; +} + +function getBumiputeraStatus(race) { + const non_bumiputera_ethnicity = ['INDIA', 'CINA', 'INDIAN', 'CHINESE']; + return !non_bumiputera_ethnicity.includes(String(race || '').toUpperCase()); +} + +function joinAddress(data) { + return [data.address1, data.address2, data.address3] + .map(line => String(line || '').trim()) + .filter(Boolean) + .join(', '); +} + +function mapReaderErrorCode(rawMessage) { + const error_handler_dictionary = { + '0x80100069': 'Tiada MyKad dikesan, sila masukkan MyKad untuk dibaca', + '0x8010000C': 'Tiada MyKad dikesan, sila masukkan MyKad untuk dibaca', + '0x80100066': 'MyKad mungkin dimasukkan terbalik, sila masukkan dengan betul', + '0x80100067': 'MyKad tidak dapat dikesan. Sila cabut dan masukkan semula kad', + '0x80100016': 'Gagal membaca MyKad. Sila pastikan kad dimasukkan dengan betul dan cuba lagi', + '0x8010002E': 'Pembaca MyKad tidak dapat dikesan, sila periksa sambungan', + '0x80100017': 'Pembaca MyKad tidak dapat dikesan, sila periksa sambungan', + }; + + let message = String(rawMessage || ''); + let codes = message.match(/0x[0-9a-fA-F]+/g) || []; + let matched = codes.reverse().find(code => error_handler_dictionary[code]); + + return matched ? error_handler_dictionary[matched] : (message || null); +} + +function getReaderErrorMessage(payload) { + if (!payload) { + return 'Pembaca MyKad tidak dapat membaca kad. Sila cuba lagi.'; + } + + let raw = payload.message || payload.error || payload.detail || ''; + return mapReaderErrorCode(raw) + || 'Pembaca MyKad tidak dapat membaca kad. Sila pastikan MyKad dimasukkan dengan betul.'; +} + +function getFetchErrorTitle(error) { + if (error && error.name === 'AbortError') { + return 'Masa menunggu pembaca MyKad telah tamat. Sila cuba lagi.'; + } + + return 'Pembaca MyKad tidak dapat dikesan. Sila pastikan perkhidmatan pembaca MyKad sedang berjalan.'; +} + +function getDisplayError(error) { + if (!error) { + return getFetchErrorTitle(error); + } + + if (error.name === 'AbortError') { + return getFetchErrorTitle(error); + } + + let message = String(error.message || ''); + if (!message || message.startsWith('Failed to fetch') || message.includes('NetworkError')) { + return getFetchErrorTitle(error); + } + + return message; +} + +async function handleMyKadReader() { + showLoader(); + + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), MYKAD_READER_TIMEOUT_MS); + + try { + const response = await fetch(getMyKadReaderEndpoint(), { + method: 'POST', + headers: { + 'Accept': 'application/json', + }, + signal: controller.signal, + }); + + const payload = await parseJsonResponse(response); + + if (!response.ok) { + throw new Error(getReaderErrorMessage(payload)); + } + + if (!payload || payload.ok !== true || !payload.data) { + throw new Error(getReaderErrorMessage(payload)); + } + + await handleMyKadData(payload.data); + } catch (error) { + Swal.fire({ + icon: 'error', + title: getDisplayError(error), + }); + } finally { + clearTimeout(timeoutId); + hideLoader(); + } +} + +function handleMyKadData(data) { + return checkIfMyKadExists(data.nric) + .then(response => { + let isResponseArray = Array.isArray(response); + let resolved_response = isResponseArray ? response.pop() : response; + + if (!resolved_response || resolved_response === 'no-data') { + populateDaftarPelangganModal(data); + } else { + let input_search_noic = document.querySelector("form[name='frmsearch'] input[name='noic']"); + let form_search_noic = document.querySelector("form[name='frmsearch']"); + + input_search_noic.value = getMyKadNumberWithoutHyphens(data.nric); + form_search_noic.submit(); + } + }) + .catch(() => { + populateDaftarPelangganModal(data); + }); +} + +function checkIfMyKadExists(myKadNumber) { + let myKadNumberWithoutHyphens = getMyKadNumberWithoutHyphens(myKadNumber); + let lookupUrl = new URL(wakil_caricustomer_endpoint, window.location.origin); + lookupUrl.searchParams.set('icno', myKadNumberWithoutHyphens); + + const csrfToken = document.querySelector('input[name="_token"]'); + + return fetch(lookupUrl.toString(), { + method: 'GET', + headers: { + "Accept": "application/json", + "X-Requested-With": "XMLHttpRequest", + "X-CSRF-Token": csrfToken ? csrfToken.value : "" + }, + credentials: "same-origin", + }).then(async response => { + let text = await response.text(); + let trimmed = (text || '').trim(); + + if (!trimmed || trimmed.charAt(0) === '<') { + return 'no-data'; + } + + try { + return JSON.parse(trimmed); + } catch (error) { + return 'no-data'; + } + }); +} + +let populateDaftarPelangganModal = (data) => { + $('#daftar_pelanggan_mykad_reader').modal('show'); + let modal_form = document.querySelector("#daftar_pelanggan_mykad_reader .modal-body .row.form-group"); + + const religions = [ + ['01', 'Islam'], + ['02', 'Hindu'], + ['03', 'Buddha'], + ['04', 'Kristian'], + ['05', 'Lain-lain'], + ]; + + const races = [ + ['M', 'Melayu'], + ['C', 'Cina'], + ['I', 'India'], + ['L', 'Lain-lain'], + ]; + + 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"); + let photo = mykad_modal.querySelector("#photo-mykad"); + + modal_form.querySelector("textarea[name='name']").value = data.name || data.gmpc_name || ''; + modal_form.querySelector("input[name='noic']").value = getMyKadNumberWithoutHyphens(data.nric); + modal_form.querySelector("input[name='tarikh_lahir']").value = formatDateOfBirth(data.dob); + modal_form.querySelector("input[name='negeri_lahir']").value = data.birth_place || ''; + modal_form.querySelector("input[name='jantina']").value = mapGender(data.gender); + modal_form.querySelector("input[name='warganegara']").checked = String(data.citizenship || '').toUpperCase() === 'WARGANEGARA'; + modal_form.querySelector("input[name='bumiputera']").checked = getBumiputeraStatus(data.race); + modal_form.querySelector("select[name='agama']").value = getCodeFromValue(data.religion, religions, '05'); + modal_form.querySelector("textarea[name='alamat']").value = joinAddress(data); + modal_form.querySelector("input[name='poskod']").value = data.postcode || ''; + modal_form.querySelector("input[name='daerah']").value = data.city || ''; + modal_form.querySelector("input[name='negeri']").value = data.state || ''; + modal_form.querySelector("input[name='age']").value = data.age != null && data.age !== '' + ? data.age + : getAgeFromDateOfBirth(data.dob); + modal_form.querySelector("select[name='bangsa']").value = getCodeFromValue(data.race, races, 'L'); + + if (data.has_photo && data.photo_base64) { + let mime = data.photo_mime || 'image/jpeg'; + photo.src = 'data:' + mime + ';base64,' + data.photo_base64; + photo_container.classList.remove('d-none'); + photo_container.classList.add('d-flex'); + } else { + photo.src = original_photo_loader; + photo_container.classList.add('d-none'); + photo_container.classList.remove('d-flex'); + } + + disablePointerEventsOnClickableInputs(); + $(modal_form.querySelector("input[name='poskod']")).trigger('change'); +}; + let hideMykadPhoto = () => { - - WebSocketManager.close(() => console.log('Websocket closed')); - let photo = document.getElementById("photo-mykad"); let photo_container = document.getElementById("photo-mykad-container"); - photo.src = original_photo_loader; + if (photo) { + photo.src = original_photo_loader; + } - photo_container.classList.add('d-none'); - photo_container.classList.remove('d-flex'); + if (photo_container) { + photo_container.classList.add('d-none'); + photo_container.classList.remove('d-flex'); + } }; -button_read_mykad.addEventListener("click", handleMyKadReader); -button_close_modal.addEventListener("click", hideMykadPhoto); +if (button_read_mykad) { + button_read_mykad.addEventListener("click", handleMyKadReader); +} + +if (button_close_modal) { + button_close_modal.addEventListener("click", hideMykadPhoto); +} diff --git a/resources/views/customers/v1/index.blade.php b/resources/views/customers/v1/index.blade.php index 61d15676..c0b5f64a 100644 --- a/resources/views/customers/v1/index.blade.php +++ b/resources/views/customers/v1/index.blade.php @@ -1277,8 +1277,7 @@ let wakil_caricustomer_endpoint = "{{ route('wakil.caricustomer') }}"; let mykad_reader_driver_endpoint = "{{ route('mykadreader.driver') }}"; - - + @endpush diff --git a/resources/views/customers/v2/index.blade.php b/resources/views/customers/v2/index.blade.php index 184bd558..ddd78267 100644 --- a/resources/views/customers/v2/index.blade.php +++ b/resources/views/customers/v2/index.blade.php @@ -1417,8 +1417,7 @@ document.getElementsByName('form-store')[0].addEventListener('keypress', functio let wakil_caricustomer_endpoint = "{{ route('wakil.caricustomer') }}"; let mykad_reader_driver_endpoint = "{{ route('mykadreader.driver') }}"; - - + @endpush diff --git a/resources/views/customers/v2/info.blade.php b/resources/views/customers/v2/info.blade.php index c9ad3a56..3b10e165 100644 --- a/resources/views/customers/v2/info.blade.php +++ b/resources/views/customers/v2/info.blade.php @@ -718,14 +718,14 @@ var kodcaw = "{{ $cawangan_info['kodcaw'] }}"; var tagarrahnbid = "{{ $cawangan_info['tagarrahnbid'] }}"; var min_komoditi = "{{ $min_komoditi }}"; - $('#daftar_gadai').on('click',function(){ + $('#daftar_gadai').on('click', function() { $("#daftar_gadai").prop('disabled', true); var noic = $('#noic').val(); var iclama = "{{ $customer_info['kplama'] }}"; var icbaru = "{{ $customer_info['kpbaru'] }}"; var outstanding_semasa = "{{ $outstanding_semasa }}"; event.preventDefault(); - if(outstanding_semasa >= 300000){ + if (outstanding_semasa >= 300000) { Swal.fire({ icon: 'error', title: 'Had Pembiayaan', @@ -733,55 +733,46 @@ }); $("#daftar_gadai").prop('disabled', false); event.preventDefault(); - if (outstanding_semasa >= 300000) { - Swal.fire({ - icon: 'error', - title: 'Had Pembiayaan', - text: 'Outstanding Pembiayaan Pelanggan Telah Melebihi Had' - }); - $("#daftar_gadai").prop('disabled', false); - event.preventDefault(); - return false; - } else { - $.ajax({ - method: 'get', - url: api_url + '/api/komuditi/check', - success: function(data) { - var check_komuditi = Object.keys(data).length; - if (check_komuditi == 0) { + return false; + } else { + $.ajax({ + method: 'get', + url: api_url + '/api/komuditi/check', + success: function(data) { + var check_komuditi = Object.keys(data).length; + if (check_komuditi == 0) { + Swal.fire({ + icon: 'error', + title: 'Unit Komoditi Berbaki Minima', + text: 'Sila Hubungi Operasi Untuk Membuat Pembelian Komoditi' + }); + $("#daftar_gadai").prop('disabled', false); + event.preventDefault(); + return false; + } else { + if (Number(data['unit_komuditi']) <= min_komoditi) { + $("#daftar_gadai").prop('disabled', false); Swal.fire({ icon: 'error', title: 'Unit Komoditi Berbaki Minima', text: 'Sila Hubungi Operasi Untuk Membuat Pembelian Komoditi' }); - $("#daftar_gadai").prop('disabled', false); event.preventDefault(); return false; } else { - if (Number(data['unit_komuditi']) <= min_komoditi) { - $("#daftar_gadai").prop('disabled', false); - Swal.fire({ - icon: 'error', - title: 'Unit Komoditi Berbaki Minima', - text: 'Sila Hubungi Operasi Untuk Membuat Pembelian Komoditi' - }); - event.preventDefault(); - return false; + if (icbaru.length > 0) { + window.location.href = + "{{ route('gadaian', ['noic' => $customer_info['kpbaru']]) }}"; } else { - if (icbaru.length > 0) { - window.location.href = - "{{ route('gadaian', ['noic' => $customer_info['kpbaru']]) }}"; - } else { - window.location.href = - "{{ route('gadaian', ['noic' => $customer_info['kplama']]) }}"; - } + window.location.href = + "{{ route('gadaian', ['noic' => $customer_info['kplama']]) }}"; } } } - }); - } - - }); + } + }); + } + }); $('a[data-toggle="tab"]').on('shown.bs.tab', function(e) { // here is the new selected tab id diff --git a/resources/views/print/resittebus_ujrah.blade.php b/resources/views/print/resittebus_ujrah.blade.php index 309fa63c..fb8da19e 100644 --- a/resources/views/print/resittebus_ujrah.blade.php +++ b/resources/views/print/resittebus_ujrah.blade.php @@ -634,7 +634,7 @@