pindah klinik belum service
This commit is contained in:
No files matched your search
+71
-10
@@ -784,10 +784,29 @@ const fetchPatientsForLoket = async (loketId, force = false) => {
|
||||
|
||||
const patientsRaw = rawData.data || [];
|
||||
|
||||
// Fetch temporary subspesialis mapping
|
||||
let subspesialisMap = {};
|
||||
try {
|
||||
const subRes = await fetch('/api/patient-subspesialis');
|
||||
if (subRes.ok) {
|
||||
subspesialisMap = await subRes.json();
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Failed to fetch temporary subspesialis mapping', e);
|
||||
}
|
||||
|
||||
// Map API data to store format
|
||||
const mappedPatients = patientsRaw.map((apiPatient, index) =>
|
||||
mapApiPatientToStoreFormat(apiPatient, index)
|
||||
).filter(p => isTodayPatient(p));
|
||||
const mappedPatients = patientsRaw.map((apiPatient, index) => {
|
||||
const mapped = mapApiPatientToStoreFormat(apiPatient, index);
|
||||
// Merge temporary subspesialis mapping
|
||||
const barcodeKey = mapped.barcode || mapped.idtiket;
|
||||
if (barcodeKey && subspesialisMap[barcodeKey]) {
|
||||
mapped.ruang = subspesialisMap[barcodeKey].namaRuang || subspesialisMap[barcodeKey].nama;
|
||||
mapped.nomorRuang = subspesialisMap[barcodeKey].nomorRuang || subspesialisMap[barcodeKey].ruang;
|
||||
mapped.kodeRuang = subspesialisMap[barcodeKey].kodeRuang || subspesialisMap[barcodeKey].id;
|
||||
}
|
||||
return mapped;
|
||||
}).filter(p => isTodayPatient(p));
|
||||
|
||||
// Deduplicate patients by idtiket
|
||||
// API returns multiple entries if patient is at multiple positions
|
||||
@@ -891,6 +910,25 @@ const fetchPatientsForLoket = async (loketId, force = false) => {
|
||||
return true; // Keep the currently processing patient
|
||||
}
|
||||
|
||||
// CRITICAL FIX: Protect patients manually moved to a different loket via changeKlinik.
|
||||
// The backend API doesn't know about this move yet, so API refresh would wipe the patient.
|
||||
// We protect them for 10 minutes (600000ms) to give admin time to process them.
|
||||
if (p.manuallyMoved && p.movedAt) {
|
||||
const timeSinceMoved = Date.now() - p.movedAt;
|
||||
const tenMinutes = 10 * 60 * 1000;
|
||||
if (timeSinceMoved < tenMinutes) {
|
||||
console.log(`🛡️ [queueStore] Protecting manually-moved patient ${p.noAntrian?.split(' |')[0]} (moved ${Math.round(timeSinceMoved/1000)}s ago) from API overwrite`);
|
||||
// Prevent the old loket's API data from overwriting this patient
|
||||
if (newPatientMap.has(key)) {
|
||||
newPatientMap.delete(key);
|
||||
}
|
||||
return true; // Keep the moved patient
|
||||
} else {
|
||||
// After 10 minutes, allow API to take over
|
||||
console.log(`⏰ [queueStore] manuallyMoved patient ${p.noAntrian?.split(' |')[0]} protection expired. Allowing API overwrite.`);
|
||||
}
|
||||
}
|
||||
|
||||
// If it's still in loket stage but marked as processed, and it's in the API batch,
|
||||
// we might be experiencing API lag. Keep it as processed.
|
||||
if (p.status === 'processed' && newPatientMap.has(key)) {
|
||||
@@ -2297,7 +2335,8 @@ const fetchPatientsForLoket = async (loketId, force = false) => {
|
||||
if (newPatient.kodeKlinik) {
|
||||
const allLokets = loketStore.lokets || [];
|
||||
const targetLoket = allLokets.find(l =>
|
||||
l.pelayanan && Array.isArray(l.pelayanan) && l.pelayanan.includes(newPatient.kodeKlinik)
|
||||
l.pelayanan && Array.isArray(l.pelayanan) &&
|
||||
(l.pelayanan.includes(newPatient.kodeKlinik) || l.pelayanan.includes(newPatient.kodeKlinik?.split('-')[0]))
|
||||
);
|
||||
if (targetLoket) {
|
||||
newPatient.loketId = targetLoket.id;
|
||||
@@ -2672,7 +2711,7 @@ const fetchPatientsForLoket = async (loketId, force = false) => {
|
||||
const getPatientsByKlinikRuang = (kodeKlinik, nomorRuang, tipeLayanan = null) => {
|
||||
return computed(() => {
|
||||
let patients = allPatients.value.filter(p =>
|
||||
p.kodeKlinik === kodeKlinik &&
|
||||
(p.kodeKlinik === kodeKlinik || (p.kodeKlinik && p.kodeKlinik.split('-')[0] === kodeKlinik)) &&
|
||||
p.nomorRuang === nomorRuang &&
|
||||
p.processStage === 'klinik-ruang'
|
||||
);
|
||||
@@ -2694,7 +2733,7 @@ const fetchPatientsForLoket = async (loketId, force = false) => {
|
||||
// Call next patient for a specific room and tipeLayanan
|
||||
const callNextKlinikRuang = (kodeKlinik, nomorRuang, tipeLayanan, allowMultiple = false) => {
|
||||
const patients = allPatients.value.filter(p =>
|
||||
p.kodeKlinik === kodeKlinik &&
|
||||
(p.kodeKlinik === kodeKlinik || (p.kodeKlinik && p.kodeKlinik.split('-')[0] === kodeKlinik)) &&
|
||||
p.nomorRuang === nomorRuang &&
|
||||
p.tipeLayanan === tipeLayanan &&
|
||||
p.processStage === 'klinik-ruang' &&
|
||||
@@ -2854,7 +2893,8 @@ const fetchPatientsForLoket = async (loketId, force = false) => {
|
||||
if (newKlinik.kode) {
|
||||
const allLokets = loketStore.lokets || [];
|
||||
const foundLoket = allLokets.find(l =>
|
||||
l.pelayanan && Array.isArray(l.pelayanan) && l.pelayanan.includes(newKlinik.kode)
|
||||
l.pelayanan && Array.isArray(l.pelayanan) &&
|
||||
(l.pelayanan.includes(newKlinik.kode) || l.pelayanan.includes(newKlinik.kode?.split('-')[0]))
|
||||
);
|
||||
|
||||
if (foundLoket) {
|
||||
@@ -2881,13 +2921,16 @@ const fetchPatientsForLoket = async (loketId, force = false) => {
|
||||
}
|
||||
|
||||
// Update the patient in allPatients
|
||||
// Mark as manuallyMoved so API refresh doesn't wipe this patient from the destination loket
|
||||
const updatedPatient = {
|
||||
...oldPatient,
|
||||
klinik: newKlinik.name,
|
||||
kodeKlinik: newKlinik.kode,
|
||||
loketId: targetLoketId,
|
||||
loket: targetLoketName,
|
||||
status: newStatus
|
||||
status: newStatus,
|
||||
manuallyMoved: isMovedToDifferentLoket ? true : (oldPatient.manuallyMoved || false),
|
||||
movedAt: isMovedToDifferentLoket ? Date.now() : (oldPatient.movedAt || null)
|
||||
};
|
||||
|
||||
allPatients.value[patientIndex] = updatedPatient;
|
||||
@@ -3022,7 +3065,8 @@ const fetchPatientsForLoket = async (loketId, force = false) => {
|
||||
if (!newPatient.loketId && newPatient.kodeKlinik) {
|
||||
const allLokets = loketStore.lokets || [];
|
||||
const targetLoket = allLokets.find(l =>
|
||||
l.pelayanan && Array.isArray(l.pelayanan) && l.pelayanan.includes(newPatient.kodeKlinik)
|
||||
l.pelayanan && Array.isArray(l.pelayanan) &&
|
||||
(l.pelayanan.includes(newPatient.kodeKlinik) || l.pelayanan.includes(newPatient.kodeKlinik?.split('-')[0]))
|
||||
);
|
||||
|
||||
if (targetLoket) {
|
||||
@@ -3061,7 +3105,8 @@ const fetchPatientsForLoket = async (loketId, force = false) => {
|
||||
// Find loket that handles BOTH the clinic AND the payment type
|
||||
const targetLoket = allLokets.find(l => {
|
||||
if (l.source !== 'api' || l.id >= 1000) return false;
|
||||
const handlesClinic = l.pelayanan && Array.isArray(l.pelayanan) && l.pelayanan.includes(clinic.kode);
|
||||
const handlesClinic = l.pelayanan && Array.isArray(l.pelayanan) &&
|
||||
(l.pelayanan.includes(clinic.kode) || l.pelayanan.includes(clinic.kode?.split('-')[0]));
|
||||
if (handlesClinic) {
|
||||
return isPaymentCompatible(paymentTypeForMatching, l.pembayaran);
|
||||
}
|
||||
@@ -3179,6 +3224,22 @@ const fetchPatientsForLoket = async (loketId, force = false) => {
|
||||
allPatients.value.push(newPatient);
|
||||
// NOTE: Kita tidak perlu incrementBarcodeCounter() di sini karena barcode berasal dari API
|
||||
|
||||
// Temporary: Save subSpesialis mapping to local JSON API
|
||||
if (subSpesialis) {
|
||||
try {
|
||||
await fetch('/api/patient-subspesialis', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
barcode: barcode,
|
||||
subspesialis: subSpesialis
|
||||
})
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('Failed to save temporary subSpesialis mapping', e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
success: true,
|
||||
|
||||
Reference in New Issue
Block a user