From d8684446e6a52bca80471fe370199ddb8da6b59e Mon Sep 17 00:00:00 2001 From: marszayn Date: Mon, 11 Aug 2025 16:21:30 +0700 Subject: [PATCH] update: guid tester --- .../SpjAdminController/SpjAdminController.cs | 56 ++++++ .../Transport/SpjAdmin/Scan/Index.cshtml | 165 +++++++++--------- .../Transport/SpjDriver/Submit/Index.cshtml | 7 +- wwwroot/driver/images/trukk.jpg | Bin 0 -> 655034 bytes 4 files changed, 140 insertions(+), 88 deletions(-) create mode 100644 wwwroot/driver/images/trukk.jpg diff --git a/Controllers/SpjAdminController/SpjAdminController.cs b/Controllers/SpjAdminController/SpjAdminController.cs index 659e422..f320788 100644 --- a/Controllers/SpjAdminController/SpjAdminController.cs +++ b/Controllers/SpjAdminController/SpjAdminController.cs @@ -7,6 +7,8 @@ namespace eSPJ.Controllers.SpjAdminController; [Route("admin")] public class SpjAdminController : Controller { + private static readonly Guid DummySpjGuid = new Guid("9f5b8f3a-1c2d-4a5b-9a7c-1234567890ab"); + private const string DummySpjNumber = "SPJ/08-2025/PKM/000519"; [HttpGet("")] public IActionResult Index() @@ -32,4 +34,58 @@ public class SpjAdminController : Controller ViewData["Id"] = id; return View("~/Views/Admin/Transport/SpjAdmin/History/Details.cshtml"); } + + [ValidateAntiForgeryToken] + [HttpPost("scan/process/{id:guid}", Name = "Admin_Scan_Process")] + public IActionResult Process(Guid id) + { + // Dummy rule: hanya GUID dummy yang dianggap valid + if (id == DummySpjGuid) + { + return Json(new { success = true, data = new { id, status = "Valid" } }); + } + return Json(new { success = false, message = "SPJ tidak ditemukan." }); + } + + // Resolve kode SPJ (contoh: "SPJ/08-2025/PKM/000519") menjadi GUID. + // Catatan: Saat ini dummy (development): setiap format SPJ yang valid bakal ke GUID baru. + // Integrasi produksi: ganti dengan query DB untuk mencari SPJ berdasarkan nomor, lalu kembalikan Id GUID yang sebenarnya. + [ValidateAntiForgeryToken] + [HttpPost("scan/resolve", Name = "Admin_Scan_Resolve")] + public IActionResult Resolve([FromForm] string code) + { + if (string.IsNullOrWhiteSpace(code)) + { + return Json(new { success = false, message = "Kode kosong." }); + } + + code = code.Trim(); + + // Jika sudah GUID, langsung kembalikan (tetap izinkan test langsung GUID dummy) + if (Guid.TryParse(code, out var guid)) + { + return Json(new { success = true, id = guid }); + } + + // Pola SPJ + var isSpj = System.Text.RegularExpressions.Regex.IsMatch( + code, + @"^SPJ/\d{2}-\d{4}/[A-Z]+/\d{6}$", + System.Text.RegularExpressions.RegexOptions.IgnoreCase + ); + + if (!isSpj) + { + return Json(new { success = false, message = "Format kode tidak dikenali." }); + } + + // Dummy mapping: jika persis sesuai nomor di atas, kembalikan GUID tetap; selain itu anggap tidak ditemukan + if (string.Equals(code, DummySpjNumber, StringComparison.OrdinalIgnoreCase)) + { + return Json(new { success = true, id = DummySpjGuid }); + } + + return Json(new { success = false, message = "SPJ tidak ditemukan." }); + } + } diff --git a/Views/Admin/Transport/SpjAdmin/Scan/Index.cshtml b/Views/Admin/Transport/SpjAdmin/Scan/Index.cshtml index a47efe5..c7da8b9 100644 --- a/Views/Admin/Transport/SpjAdmin/Scan/Index.cshtml +++ b/Views/Admin/Transport/SpjAdmin/Scan/Index.cshtml @@ -105,7 +105,7 @@

Atau input manual:

-
+ @Html.AntiForgeryToken()
{ - if (response.success) { - this.showModal('success', 'Scan Berhasil!', 'SPJ berhasil ditemukan dan diproses.', true); - setTimeout(() => { - this.hideResult(); - this.manualInput.value = ''; - }, 2000); - } else { - this.showModal('error', 'SPJ Tidak Ditemukan', response.message || 'Kode SPJ tidak ditemukan dalam database.', true); - } - }, - error: (xhr, status, error) => { - let errorMessage = 'Terjadi kesalahan saat memproses scan.'; - - if (xhr.responseJSON && xhr.responseJSON.message) { - errorMessage = xhr.responseJSON.message; - } else if (xhr.status === 404) { - errorMessage = 'SPJ tidak ditemukan dalam database.'; - } else if (xhr.status === 500) { - errorMessage = 'Terjadi kesalahan server. Silakan coba lagi.'; - } - - this.showModal('error', 'Error', errorMessage, true); - } - }); - */ + isGuid(value) { + const re = /^[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$/; + return re.test((value || '').trim()); } - // Mock response untuk testing - mockResponse(code) { - console.log(`Testing scan untuk kode: ${code}`); - - setTimeout(() => { - const validCodes = [ - 'SPJ001', 'SPJ002', 'SPJ003', 'SPJ004', 'SPJ005', - 'TEST123', 'TEST456', 'TEST789', - '12345', '67890', '11111', '22222', - 'ABCDEF', 'GHIJKL', 'MNOPQR' - ]; - - const isValid = validCodes.some(validCode => - validCode.toLowerCase() === code.toLowerCase() - ); - - if (isValid) { - console.log(`✅ Kode ${code} VALID - menampilkan success`); - - // Format tanggal Indonesia - const now = new Date(); - const tanggal = now.toLocaleDateString('id-ID', { - weekday: 'long', - year: 'numeric', - month: 'long', - day: 'numeric' - }); - const waktu = now.toLocaleTimeString('id-ID', { - hour: '2-digit', - minute: '2-digit' - }); - - this.showSuccessModal(code, tanggal, waktu); - - // Scanner tetap aktif, tidak perlu reset tombol - setTimeout(() => { - this.hideResult(); - this.manualInput.value = ''; - }, 3000); - } else { - console.log(`❌ Kode ${code} TIDAK VALID - menampilkan error`); - this.showErrorModal(code); - } - }, 1000); + isSpjCode(value) { + const re = /^SPJ\/\d{2}-\d{4}\/[A-Z]+\/\d{6}$/i; + return re.test((value || '').trim()); } + processUrlFor(id) { + const basePath = '@Url.Content("~/admin/scan/process/")'; + return basePath + encodeURIComponent(id); + } + + postGuid(id) { + const url = this.processUrlFor(id); + return $.ajax({ + url: url, + type: 'POST', + headers: { 'RequestVerificationToken': $('input[name="__RequestVerificationToken"]').val() } + }); + } + + resolveSpj(code) { + const url = '@Url.Content("~/admin/scan/resolve")'; + return $.ajax({ + url: url, + type: 'POST', + headers: { 'RequestVerificationToken': $('input[name="__RequestVerificationToken"]').val() }, + data: { code } + }); + } + + async processScanCode(code) { + this.showModal('loading', 'Memproses...', 'Sedang memverifikasi kode SPJ...', false); + + try { + let guid = null; + const trimmed = (code || '').trim(); + + if (this.isGuid(trimmed)) { + guid = trimmed; + } else if (this.isSpjCode(trimmed)) { + // minta backend resolve SPJ ke GUID + const rs = await this.resolveSpj(trimmed); + if (!rs || rs.success !== true || !rs.id) { + throw new Error((rs && rs.message) ? rs.message : 'Gagal resolve SPJ ke GUID.'); + } + guid = rs.id; + } else { + throw new Error('Format kode tidak dikenali. Masukkan GUID atau nomor SPJ yang valid.'); + } + + // POST GUID ke process endpoint + const resp = await this.postGuid(guid); + console.debug('process response', resp); + if (resp && resp.success) { + const now = new Date(); + const tanggal = now.toLocaleDateString('id-ID', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }); + const waktu = now.toLocaleTimeString('id-ID', { hour: '2-digit', minute: '2-digit' }); + this.showSuccessModal(trimmed, tanggal, waktu); + } else { + this.showModal('error', 'SPJ Tidak Ditemukan', (resp && resp.message) ? resp.message : 'Kode SPJ tidak ditemukan dalam database.', true); + } + } catch (xhrOrErr) { + let message = ''; + if (xhrOrErr && xhrOrErr.responseJSON) { + message = xhrOrErr.responseJSON.message || 'Terjadi kesalahan saat memproses.'; + } else if (xhrOrErr && xhrOrErr.responseText) { + message = xhrOrErr.responseText; + } else if (xhrOrErr instanceof Error) { + message = xhrOrErr.message; + } else { + message = 'Terjadi kesalahan saat memproses scan.'; + } + console.error('processScanCode error', xhrOrErr); + this.showModal('error', 'Error', message, true); + } + } + + async retryScan() { this.hideResult(); this.hideError(); diff --git a/Views/Admin/Transport/SpjDriver/Submit/Index.cshtml b/Views/Admin/Transport/SpjDriver/Submit/Index.cshtml index b50d9bf..c32f5a1 100644 --- a/Views/Admin/Transport/SpjDriver/Submit/Index.cshtml +++ b/Views/Admin/Transport/SpjDriver/Submit/Index.cshtml @@ -32,10 +32,12 @@