diff --git a/nuxt.config.ts b/nuxt.config.ts index ba45147..3bf7f25 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -37,7 +37,7 @@ export default defineNuxtConfig({ // @ts-expect-error config.server.https = true; // @ts-expect-error - config.server.host = '10.10.150.175'; + config.server.host = '10.10.150.114'; // @ts-expect-error config.server.port = 3000; } catch (e) { diff --git a/stores/queueStore.js b/stores/queueStore.js index ee1bda8..37b9c9b 100644 --- a/stores/queueStore.js +++ b/stores/queueStore.js @@ -927,6 +927,42 @@ export const useQueueStore = defineStore('queue', () => { syncCountersWithState(); // Re-initialize counters after reset }; + /** + * Check if patient's payment type is compatible with loket's accepted payments + * Maps various payment names to standardized categories + * Handles complex names like "UMUM / JKMM / SPM / DLL" + */ + const isPaymentCompatible = (patientPayment, loketPayments) => { + if (!loketPayments || loketPayments.length === 0) return true; // No restriction + if (!patientPayment) return false; + + const normalizedPatient = String(patientPayment).toUpperCase().trim(); + + // Map patient payment to category + const patientCategory = + (normalizedPatient.includes('JKN') || normalizedPatient.includes('BPJS')) ? 'JKN' : + normalizedPatient.includes('EKSEKUTIF') || normalizedPatient.includes('VIP') ? 'EKSEKUTIF' : + 'UMUM'; // Default to UMUM for non-JKN, non-EKSEKUTIF + + // Check if loket accepts this category + return loketPayments.some(lp => { + const normalized = String(lp).toUpperCase().trim(); + + // Handle exact match + if (normalized === patientCategory) return true; + + // Handle partial matches for complex payment types like "UMUM / JKMM / SPM / DLL" + if (patientCategory === 'UMUM' && normalized.includes('UMUM')) return true; + if (patientCategory === 'JKN' && (normalized.includes('JKN') || normalized.includes('BPJS'))) return true; + if (patientCategory === 'EKSEKUTIF' && (normalized.includes('EKSEKUTIF') || normalized.includes('VIP'))) return true; + + // Handle alias: BPJS = JKN (only this alias is allowed) + if (normalized === 'BPJS' && patientCategory === 'JKN') return true; + + return false; + }); + }; + // Action: Ambil Antrean Masuk dari Anjungan (Reservoir -> Waiting Room) // "fungsi ini juga sesuaikan dengan idloket dan klinik id" // "hanya memanggil tiket dari loket lain harus tiket menunggu yang sesuai id loket dan id kliniknya" @@ -955,7 +991,13 @@ export const useQueueStore = defineStore('queue', () => { const thisLoket = loketStore.getLoketById(parseInt(targetId)); // Enforce clinic mapping (pelayanan) if (thisLoket && thisLoket.pelayanan && Array.isArray(thisLoket.pelayanan)) { - if (thisLoket.pelayanan.includes(p.kodeKlinik)) return true; + if (thisLoket.pelayanan.includes(p.kodeKlinik)) { + // NEW: Check payment compatibility + if (!isPaymentCompatible(p.pembayaran, thisLoket.pembayaran)) { + return false; + } + return true; + } } return false; @@ -1060,7 +1102,13 @@ export const useQueueStore = defineStore('queue', () => { const thisLoket = loketStore.getLoketById(parseInt(targetId)); if (thisLoket && thisLoket.pelayanan && Array.isArray(thisLoket.pelayanan)) { - if (thisLoket.pelayanan.includes(p.kodeKlinik)) return true; + if (thisLoket.pelayanan.includes(p.kodeKlinik)) { + // NEW: Check payment compatibility + if (!isPaymentCompatible(p.pembayaran, thisLoket.pembayaran)) { + return false; + } + return true; + } } return false; @@ -2006,31 +2054,57 @@ export const useQueueStore = defineStore('queue', () => { // Determine payment type for matching (normalize BPJS to JKN for API compatibility) const paymentTypeForMatching = paymentType === "BPJS" ? "JKN" : paymentType; + console.log('🔍 [queueStore] Searching lokets...'); + console.log(' Total lokets:', allLokets.length); + console.log(' API lokets (id < 1000):', allLokets.filter(l => l.source === 'api' && l.id < 1000).length); + console.log(' Looking for clinic:', clinic.kode, 'payment:', paymentTypeForMatching); + // Find loket that handles BOTH the clinic AND the payment type const targetLoket = allLokets.find(l => { + // Check source: only use API lokets (id < 1000), not local eksekutif + if (l.source !== 'api' || l.id >= 1000) return false; + // Check if loket handles the clinic const handlesClinic = l.pelayanan && Array.isArray(l.pelayanan) && l.pelayanan.includes(clinic.kode); - if (!handlesClinic) return false; - // Check if loket accepts the payment type - const acceptsPayment = l.pembayaran && Array.isArray(l.pembayaran) && - l.pembayaran.some(p => { - // Handle case-insensitive matching and common variations - const normalizedP = String(p).toUpperCase().trim(); - const normalizedPayment = String(paymentTypeForMatching).toUpperCase().trim(); - return normalizedP === normalizedPayment || - (normalizedPayment === "JKN" && normalizedP === "BPJS") || - (normalizedPayment === "BPJS" && normalizedP === "JKN"); - }); + if (handlesClinic) { + // Debug: This loket handles the clinic, now check payment + console.log(` ✓ Loket ${l.id} (${l.namaLoket}) handles clinic ${clinic.kode}`); + console.log(` Pembayaran array:`, l.pembayaran); + + // NEW: Use isPaymentCompatible helper for robust payment matching + const acceptsPayment = isPaymentCompatible(paymentTypeForMatching, l.pembayaran); + console.log(` Accepts payment ${paymentTypeForMatching}:`, acceptsPayment); + + if (acceptsPayment) { + console.log(` ✅ MATCH FOUND: Loket ${l.id}`); + return true; + } + } - return handlesClinic && acceptsPayment; + return false; }); - const idloket = targetLoket ? String(targetLoket.id) : "2"; // Default fallback to "2" if not found + // BLOCK REGISTRATION: No fallback to loket 2 + if (!targetLoket) { + console.error(`❌ [queueStore] No loket found for clinic ${clinic.kode} (${clinic.name}) with payment ${paymentTypeForMatching}`); + console.warn(`⚠️ [queueStore] Available lokets:`, allLokets.filter(l => l.source === 'api').map(l => ({ + id: l.id, + nama: l.namaLoket, + pelayanan: l.pelayanan, + pembayaran: l.pembayaran + }))); + + return { + success: false, + message: `Maaf, klinik "${clinic.name}" dengan pembayaran "${paymentTypeForMatching}" belum tersedia. Silakan hubungi petugas pendaftaran.` + }; + } - console.log('🎯 [queueStore] Target Loket:', targetLoket ? `${targetLoket.namaLoket} (ID: ${targetLoket.id})` : 'Not found (using fallback)', '| Accepts Payment:', targetLoket?.pembayaran); + console.log('🎯 [queueStore] Target Loket:', `${targetLoket.namaLoket} (ID: ${targetLoket.id})`, '| Accepts Payment:', targetLoket.pembayaran); // 2. Determine idpembayaran based on paymentType + const idloket = String(targetLoket.id); // BPJS (JKN) = "2", UMUM and others = "1" const idpembayaran = paymentType === "BPJS" ? "2" : "1";