update flow anjungan,checkin,admin,dan klinik ruang

This commit is contained in:
bagus-arie05
2026-01-07 11:35:55 +07:00
parent 9e399c9f64
commit 155e3d9ea7
7 changed files with 842 additions and 63 deletions
+99 -19
View File
@@ -222,6 +222,7 @@ export const useQueueStore = defineStore('queue', () => {
return {
all: patients,
waiting: patients.filter(p => p.status === 'waiting'),
menunggu: patients.filter(p => p.status === 'menunggu'), // Pasien yang belum dipanggil
diLoket: patients.filter(p => p.status === 'di-loket'),
terlambat: patients.filter(p => p.status === 'terlambat'),
pending: patients.filter(p => p.status === 'pending'),
@@ -253,7 +254,10 @@ export const useQueueStore = defineStore('queue', () => {
};
const targetStage = stageMap[adminType];
// Prioritaskan pasien dengan status 'menunggu' (yang belum dipanggil)
const nextPatient = allPatients.value.find(p =>
p.status === 'menunggu' && p.processStage === targetStage
) || allPatients.value.find(p =>
p.status === 'waiting' && p.processStage === targetStage
);
@@ -261,17 +265,28 @@ export const useQueueStore = defineStore('queue', () => {
return { success: false, message: "Tidak ada pasien selanjutnya" };
}
if (quotaUsed.value >= 150) {
return { success: false, message: "Quota sudah penuh" };
}
// Hitung kuota yang tersedia
const menungguCount = allPatients.value.filter(p =>
p.status === 'menunggu' && p.processStage === targetStage
).length;
const diLoketCount = allPatients.value.filter(p =>
p.status === 'di-loket' && p.processStage === targetStage
).length;
const availableQuota = 150 - diLoketCount;
// Update dengan cara yang Vue reactive
const index = allPatients.value.findIndex(p => p.no === nextPatient.no);
if (index !== -1) {
allPatients.value[index] = { ...allPatients.value[index], status: "di-loket" };
if (availableQuota <= 0) {
return { success: false, message: "Kuota sudah penuh" };
}
quotaUsed.value++;
if (menungguCount === 0) {
return { success: false, message: "Tidak ada pasien yang menunggu untuk dipanggil" };
}
// Update status dari 'menunggu' menjadi 'waiting' (sudah dipanggil, bisa check-in)
const index = allPatients.value.findIndex(p => p.no === nextPatient.no);
if (index !== -1) {
allPatients.value[index] = { ...allPatients.value[index], status: "waiting" };
}
return {
success: true,
@@ -287,30 +302,49 @@ export const useQueueStore = defineStore('queue', () => {
};
const targetStage = stageMap[adminType];
// Prioritaskan pasien dengan status 'menunggu' (yang belum dipanggil)
const menungguList = allPatients.value.filter(p =>
p.status === 'menunggu' && p.processStage === targetStage
);
const waitingList = allPatients.value.filter(p =>
p.status === 'waiting' && p.processStage === targetStage
);
const patientsToCall = waitingList.slice(0, count);
// Gabungkan: menunggu dulu, baru waiting
const combinedList = [...menungguList, ...waitingList];
if (patientsToCall.length === 0) {
if (combinedList.length === 0) {
return { success: false, message: "Tidak ada pasien yang menunggu" };
}
if (quotaUsed.value + patientsToCall.length > 150) {
return { success: false, message: "Quota tidak mencukupi" };
// Hitung kuota yang tersedia
const diLoketCount = allPatients.value.filter(p =>
p.status === 'di-loket' && p.processStage === targetStage
).length;
const availableQuota = 150 - diLoketCount;
// Kuota yang bisa dipanggil = min(count yang diminta, jumlah pasien menunggu, kuota tersedia)
const maxCallable = Math.min(count, menungguList.length, availableQuota);
if (maxCallable <= 0) {
if (menungguList.length === 0) {
return { success: false, message: "Tidak ada pasien yang menunggu untuk dipanggil" };
}
if (availableQuota <= 0) {
return { success: false, message: "Kuota sudah penuh. Tidak bisa memanggil pasien lagi" };
}
}
// Update dengan cara yang Vue reactive
const patientsToCall = combinedList.slice(0, maxCallable);
// Update status dari 'menunggu' menjadi 'waiting' (sudah dipanggil, bisa check-in)
patientsToCall.forEach((patient) => {
const index = allPatients.value.findIndex(p => p.no === patient.no);
if (index !== -1) {
allPatients.value[index] = { ...allPatients.value[index], status: "di-loket" };
allPatients.value[index] = { ...allPatients.value[index], status: "waiting" };
}
});
quotaUsed.value += patientsToCall.length;
return {
success: true,
message: `Memanggil ${patientsToCall.length} pasien ke loket`,
@@ -495,6 +529,41 @@ export const useQueueStore = defineStore('queue', () => {
};
};
const createAntreanKlinikRuang = (klinikRuang, ruang, patient = null, adminType = 'klinik') => {
const newNo = allPatients.value.length + 1;
const timestamp = new Date();
const barcode = patient ? patient.barcode : `250811${String(timestamp.getTime()).slice(-6)}`;
const newPatient = {
no: newNo,
jamPanggil: `${String(timestamp.getHours()).padStart(2, "0")}:${String(
timestamp.getMinutes()
).padStart(2, "0")}`,
barcode: barcode,
noAntrian: `KR${String(newNo).padStart(4, "0")} | ${klinikRuang.namaKlinik} - Ruang ${ruang.nomorRuang} - ${barcode}`,
shift: "Shift 1",
klinik: klinikRuang.namaKlinik,
ruang: ruang.namaRuang,
kodeKlinik: klinikRuang.kodeKlinik,
nomorRuang: ruang.nomorRuang,
nomorScreen: ruang.nomorScreen,
fastTrack: "TIDAK",
pembayaran: patient ? patient.pembayaran : "UMUM",
status: "waiting",
processStage: "klinik",
createdAt: timestamp.toISOString(),
referencePatient: patient ? patient.noAntrian : null,
};
allPatients.value.push(newPatient);
return {
success: true,
message: `Antrean ${klinikRuang.namaKlinik} Ruang ${ruang.nomorRuang} berhasil dibuat dan akan ditampilkan di layar antrian`,
patient: newPatient,
};
};
const changeKlinik = (patient, newKlinik, adminType = 'loket') => {
const patientIndex = allPatients.value.findIndex((p) => p.no === patient.no);
@@ -548,8 +617,9 @@ export const useQueueStore = defineStore('queue', () => {
// Format nomor antrean: UMXXXX | Onsite - barcode
const noAntrian = `UM${String(newNo).padStart(4, "0")} | Onsite - ${barcode}`;
// Determine status based on visit type
const status = visitType === 'SEKARANG' ? 'waiting' : 'pending';
// Status awal untuk pasien dari anjungan adalah "menunggu" (belum dipanggil)
// Hanya setelah dipanggil oleh admin loket, status berubah menjadi "waiting" (bisa check-in)
const status = 'menunggu';
const newPatient = {
no: newNo,
@@ -641,7 +711,16 @@ export const useQueueStore = defineStore('queue', () => {
const patient = allPatients.value[patientIndex];
console.log('✅ Patient found:', patient);
// Only allow check-in if status is waiting or pending
// Only allow check-in if status is waiting (sudah dipanggil) or pending
// Pasien dengan status "menunggu" belum bisa check-in (belum dipanggil)
if (patient.status === 'menunggu') {
console.log('⚠️ Patient status is menunggu (belum dipanggil):', patient.status);
return {
success: false,
message: `Pasien belum dipanggil oleh admin loket. Mohon menunggu hingga nomor antrean Anda dipanggil.`
};
}
if (patient.status !== 'waiting' && patient.status !== 'pending') {
console.log('⚠️ Patient status is not waiting/pending:', patient.status);
return {
@@ -685,6 +764,7 @@ export const useQueueStore = defineStore('queue', () => {
processPatient,
createAntreanKlinik,
createAntreanPenunjang,
createAntreanKlinikRuang,
changeKlinik,
processNextQueue,
getPatientsByStage,