push change sort pasien next process

This commit is contained in:
Fanrouver
2026-02-10 12:18:02 +07:00
parent e686ddad57
commit 6af3f58e89
2 changed files with 70 additions and 46 deletions
+25 -6
View File
@@ -649,6 +649,17 @@ const allPatientsForStage = computed(() => {
}));
}
// Sorting: Fast Track first, then by sequence number (no)
combined.sort((a, b) => {
const aFT = (a.fastTrack ?? "").toString().trim().toUpperCase() === "YA";
const bFT = (b.fastTrack ?? "").toString().trim().toUpperCase() === "YA";
if (aFT && !bFT) return -1;
if (!aFT && bFT) return 1;
return (a.no || 0) - (b.no || 0);
});
return combined;
});
@@ -717,16 +728,24 @@ const nextQueueInfo = computed(() => {
const currentPatientNo = currentProcessingPatient.value?.no;
const targetLoketId = parseInt(loketId.value);
// Filter diLoketPatients to only show patients for THIS loket
const loketFilteredPatients = (diLoketPatients.value || []).filter((p) => {
// Only show patients assigned to this specific loket
// Filter ONLY di-loket patients assigned to this loket
const eligibleDiLoket = (diLoketPatients.value || []).filter((p) => {
return p.loketId && String(p.loketId) === String(targetLoketId);
});
// Sort them as per table (Fast Track, then No)
const sorted = [...eligibleDiLoket].sort((a, b) => {
const aFT = (a.fastTrack ?? "").toString().trim().toUpperCase() === "YA";
const bFT = (b.fastTrack ?? "").toString().trim().toUpperCase() === "YA";
if (aFT && !bFT) return -1;
if (!aFT && bFT) return 1;
return (a.no || 0) - (b.no || 0);
});
// Find next patient (excluding current processing patient)
const nextPatient =
loketFilteredPatients.find((p) => p.no !== currentPatientNo) ||
loketFilteredPatients[0];
const nextPatient = sorted.find((p) => p.no !== currentPatientNo);
if (nextPatient) {
return `Antrian berikutnya: ${nextPatient.noAntrian.split(" |")[0]}`;
+45 -40
View File
@@ -1015,6 +1015,25 @@ export const useQueueStore = defineStore('queue', () => {
syncCountersWithState(); // Re-initialize counters after reset
};
/**
* Helper to sort patients for calling/process selection
* Priority: Fast Track ("YA") first, then by sequence number (no)
*/
const sortPatientsForCalling = (patients) => {
if (!patients || !Array.isArray(patients)) return [];
return [...patients].sort((a, b) => {
const aFT = (a.fastTrack ?? "").toString().trim().toUpperCase() === "YA";
const bFT = (b.fastTrack ?? "").toString().trim().toUpperCase() === "YA";
if (aFT && !bFT) return -1;
if (!aFT && bFT) return 1;
const numA = parseInt(a.no) || 0;
const numB = parseInt(b.no) || 0;
return numA - numB;
});
};
/**
* Check if patient's payment type is compatible with loket's accepted payments
* Maps various payment names to standardized categories
@@ -1105,7 +1124,10 @@ export const useQueueStore = defineStore('queue', () => {
// PRIORITAS: Hanya ambil pasien dengan status 'menunggu' (Antrean Baru dari Anjungan)
// "bukan untuk memanggil pasien tapi tiket baru dari anjungan yang statusnya menunggu"
const nextPatient = eligiblePatients.find(p => p.status === 'menunggu');
// SEQUENTIAL: Sort by Fast Track and Queue No before picking the first matching patient
const waitingPatients = eligiblePatients.filter(p => p.status === 'menunggu');
const sortedWaiting = sortPatientsForCalling(waitingPatients);
const nextPatient = sortedWaiting[0];
if (!nextPatient) {
return { success: false, message: `Tidak ada antrean baru yang sesuai untuk ${adminType} ${targetId || ''}` };
@@ -1208,7 +1230,8 @@ export const useQueueStore = defineStore('queue', () => {
});
// Hanya ambil pasien status 'menunggu'
const menungguList = eligiblePatients.filter(p => p.status === 'menunggu');
// SEQUENTIAL: Sort by Fast Track and Queue No
const menungguList = sortPatientsForCalling(eligiblePatients.filter(p => p.status === 'menunggu'));
if (menungguList.length === 0) {
return { success: false, message: `Tidak ada antrean baru yang sesuai untuk ${adminType} ${targetId || ''}` };
@@ -2448,7 +2471,7 @@ export const useQueueStore = defineStore('queue', () => {
};
};
// FIX: Explicit implementation of processNextQueue to prevent cross-loket leakage
// FIX: Explicit implementation of processNextQueue to target ONLY 'di-loket' patients
const processNextQueueCorrected = (adminType = 'loket', specificId = null) => {
// 1. Determine target stage and key
const stageMap = { 'loket': 'loket', 'klinik': 'klinik', 'penunjang': 'penunjang' };
@@ -2457,55 +2480,37 @@ export const useQueueStore = defineStore('queue', () => {
console.log(`🚀 [processNextQueue] Processing for ${key} (Stage: ${targetStage})`);
// 2. Find next patient (Status: 'menunggu' -> 'anjungan')
// Prioritaskan yang assigned ke loket ini (loketId) jika ada match
let nextPatient = null;
if (adminType === 'loket' && specificId) {
// Cari yang spesifik untuk loket ini dulu
nextPatient = allPatients.value.find(p =>
p.status === 'menunggu' &&
p.processStage === targetStage &&
String(p.loketId) === String(specificId)
);
}
// Jika tidak ada yang spesifik, cari yang umum (menunggu & loketId null/match)
if (!nextPatient) {
nextPatient = allPatients.value.find(p =>
p.status === 'menunggu' &&
p.processStage === targetStage &&
(adminType !== 'loket' || !p.loketId || String(p.loketId) === String(specificId))
);
}
// Fallback: Check 'anjungan' status if needed (though usually 'menunggu' is for calling)
if (!nextPatient) {
nextPatient = allPatients.value.find(p =>
p.status === 'anjungan' &&
p.processStage === targetStage &&
(adminType !== 'loket' || String(p.loketId) === String(specificId))
);
}
// 2. Find next patient ONLY from 'di-loket' status
// These are patients who have already checked in or been moved to 'di-loket'
const eligiblePatients = allPatients.value.filter(p =>
p.status === 'di-loket' &&
p.processStage === targetStage &&
(adminType !== 'loket' || String(p.loketId) === String(specificId))
);
// Exclude the current processing patient to find the TRULY next one
const currentNum = currentProcessingPatient.value[key]?.no;
const waitingDiLoket = eligiblePatients.filter(p => p.no !== currentNum);
// 3. Sort by priority (Fast Track, then No)
const sorted = sortPatientsForCalling(waitingDiLoket);
const nextPatient = sorted[0];
if (!nextPatient) {
return { success: false, message: "Tidak ada antrean yang menunggu untuk diproses." };
return { success: false, message: "Tidak ada antrean 'Di Loket' yang menunggu untuk diproses." };
}
// 3. Update Patient Status (di-loket)
// 4. Update Current Processing ISOLATED by key
// We don't change status because it's already 'di-loket'
// But we update the lastCalledAt and set it as current
const index = allPatients.value.findIndex(p => p.no === nextPatient.no);
if (index !== -1) {
const updatedPatient = {
...allPatients.value[index],
status: 'di-loket',
loketId: specificId || allPatients.value[index].loketId, // Ensure loketId is set
lastCalledAt: new Date().toISOString()
};
allPatients.value[index] = updatedPatient;
syncApiPatientStatus(allPatients.value[index], 'di-loket');
// 4. Set Current Processing ISOLATED by key
currentProcessingPatient.value[key] = updatedPatient;
return {