Files
web-antrean/stores/queueStore.js
T
2025-10-21 08:31:00 +07:00

354 lines
10 KiB
JavaScript

// stores/queueStore.js
import { defineStore } from 'pinia';
import { ref, computed } from 'vue';
export const useQueueStore = defineStore('queue', () => {
// State
const allPatients = ref([
{
no: 1,
jamPanggil: "12:49",
barcode: "250811100163",
noAntrian: "UM1001 | Online - 250811100163",
shift: "Shift 1",
klinik: "KANDUNGAN",
fastTrack: "UMUM",
pembayaran: "UMUM",
status: "waiting", // waiting, di-loket, terlambat, pending, processed
processStage: "loket", // loket, klinik, penunjang
createdAt: new Date().toISOString(),
},
{
no: 2,
jamPanggil: "10:52",
barcode: "250811100155",
noAntrian: "UM1002 | Online - 250811100155",
shift: "Shift 1",
klinik: "IPD",
fastTrack: "UMUM",
pembayaran: "UMUM",
status: "waiting",
processStage: "loket",
createdAt: new Date().toISOString(),
},
{
no: 3,
jamPanggil: "09:30",
barcode: "250811100200",
noAntrian: "UM1003 | Online - 250811100200",
shift: "Shift 1",
klinik: "SARAF",
fastTrack: "UMUM",
pembayaran: "UMUM",
status: "waiting",
processStage: "loket",
createdAt: new Date().toISOString(),
},
{
no: 4,
jamPanggil: "14:15",
barcode: "250811100210",
noAntrian: "UM1004 | Online - 250811100210",
shift: "Shift 1",
klinik: "THT",
fastTrack: "UMUM",
pembayaran: "UMUM",
status: "waiting",
processStage: "loket",
createdAt: new Date().toISOString(),
},
]);
const quotaUsed = ref(5);
const currentProcessingPatient = ref({
loket: null,
klinik: null,
penunjang: null,
});
const kliniks = ref([
{ id: 1, name: "KANDUNGAN" },
{ id: 2, name: "IPD" },
{ id: 3, name: "THT" },
{ id: 4, name: "SARAF" },
{ id: 5, name: "JIWA" },
{ id: 6, name: "BEDAH" },
{ id: 7, name: "MATA" },
{ id: 8, name: "ANAK" },
{ id: 9, name: "KULIT" },
]);
const penunjangs = ref([
{ id: 1, name: "LABORATORIUM" },
{ id: 2, name: "RADIOLOGI" },
{ id: 3, name: "USG" },
{ id: 4, name: "CT SCAN" },
{ id: 5, name: "MRI" },
{ id: 6, name: "EKG" },
{ id: 7, name: "ENDOSKOPI" },
{ id: 8, name: "FISIOTERAPI" },
{ id: 9, name: "FARMASI" },
]);
// Computed - Filter berdasarkan process stage dan status
const getPatientsByStage = (stage) => {
return computed(() => {
const patients = allPatients.value.filter(p => p.processStage === stage);
return {
all: patients,
waiting: patients.filter(p => p.status === 'waiting'),
diLoket: patients.filter(p => p.status === 'di-loket'),
terlambat: patients.filter(p => p.status === 'terlambat'),
pending: patients.filter(p => p.status === 'pending'),
};
});
};
// Total pasien per stage
const getTotalPasienByStage = (stage) => {
return computed(() =>
allPatients.value.filter(p => p.processStage === stage).length
);
};
const totalPasien = computed(() => allPatients.value.length);
// Actions
const callNext = (adminType = 'loket') => {
const stageMap = {
'loket': 'loket',
'klinik': 'klinik',
'penunjang': 'penunjang'
};
const targetStage = stageMap[adminType];
const nextPatient = allPatients.value.find(p =>
p.status === 'waiting' && p.processStage === targetStage
);
if (!nextPatient) {
return { success: false, message: "Tidak ada pasien selanjutnya" };
}
if (quotaUsed.value >= 150) {
return { success: false, message: "Quota sudah penuh" };
}
nextPatient.status = "di-loket";
currentProcessingPatient.value[adminType] = nextPatient;
quotaUsed.value++;
return {
success: true,
message: `Memanggil pasien ${nextPatient.noAntrian.split(" |")[0]}`,
};
};
const callMultiplePatients = (count, adminType = 'loket') => {
const stageMap = {
'loket': 'loket',
'klinik': 'klinik',
'penunjang': 'penunjang'
};
const targetStage = stageMap[adminType];
const waitingList = allPatients.value.filter(p =>
p.status === 'waiting' && p.processStage === targetStage
);
const patientsToCall = waitingList.slice(0, count);
if (patientsToCall.length === 0) {
return { success: false, message: "Tidak ada pasien yang menunggu" };
}
if (quotaUsed.value + patientsToCall.length > 150) {
return { success: false, message: "Quota tidak mencukupi" };
}
patientsToCall.forEach((patient) => {
patient.status = "di-loket";
});
quotaUsed.value += patientsToCall.length;
return {
success: true,
message: `Memanggil ${patientsToCall.length} pasien ke loket`,
};
};
const processPatient = (patient, action, adminType = 'loket') => {
const patientCode = patient.noAntrian.split(" |")[0];
let message = "";
switch (action) {
case "check-in":
// Jika check-in di loket, pindahkan ke klinik dengan status di-loket
if (adminType === 'loket') {
patient.status = "di-loket"; // Langsung masuk tabel Di Loket Klinik
patient.processStage = "klinik";
message = `Pasien ${patientCode} berhasil check in dan masuk ke Tabel Loket Klinik`;
}
// Jika check-in di klinik, selesai
else if (adminType === 'klinik') {
patient.status = "processed";
message = `Pasien ${patientCode} berhasil check in di Klinik`;
}
// Jika check-in di penunjang, selesai
else if (adminType === 'penunjang') {
patient.status = "processed";
message = `Pasien ${patientCode} berhasil check in di Penunjang`;
}
// Clear current processing di admin yang melakukan check-in
if (currentProcessingPatient.value[adminType]?.no === patient.no) {
currentProcessingPatient.value[adminType] = null;
}
break;
case "terlambat":
patient.status = "terlambat";
if (currentProcessingPatient.value[adminType]?.no === patient.no) {
currentProcessingPatient.value[adminType] = null;
}
message = `Pasien ${patientCode} ditandai terlambat`;
break;
case "pending":
patient.status = "pending";
if (currentProcessingPatient.value[adminType]?.no === patient.no) {
currentProcessingPatient.value[adminType] = null;
}
message = `Pasien ${patientCode} di-pending`;
break;
case "aktifkan":
if (patient.status === "terlambat" || patient.status === "pending") {
patient.status = "di-loket";
message = `Pasien ${patientCode} diaktifkan kembali`;
}
break;
case "proses":
currentProcessingPatient.value[adminType] = patient;
message = `Memproses pasien ${patientCode}`;
break;
}
return { success: true, message };
};
const createAntreanKlinik = (klinik, adminType = 'loket') => {
const newNo = allPatients.value.length + 1;
const timestamp = new Date();
const 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: `KL${String(newNo).padStart(4, "0")} | Klinik - ${barcode}`,
shift: "Shift 1",
klinik: klinik.name,
fastTrack: "UMUM",
pembayaran: "UMUM",
status: "di-loket", // Langsung masuk tabel Di Loket Klinik
processStage: "klinik",
createdAt: timestamp.toISOString(),
};
allPatients.value.push(newPatient);
return {
success: true,
message: `Antrean klinik ${klinik.name} berhasil dibuat dan masuk ke Tabel Loket Klinik`,
patient: newPatient,
};
};
const createAntreanPenunjang = (penunjang, patient = null, adminType = 'loket') => {
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: `PN${String(newNo).padStart(4, "0")} | Penunjang - ${barcode}`,
shift: "Shift 1",
klinik: penunjang.name,
fastTrack: "UMUM",
pembayaran: patient ? patient.pembayaran : "UMUM",
status: "di-loket", // Langsung masuk tabel Di Loket Penunjang
processStage: "penunjang",
createdAt: timestamp.toISOString(),
referencePatient: patient ? patient.noAntrian : null,
};
allPatients.value.push(newPatient);
return {
success: true,
message: `Antrean penunjang ${penunjang.name} berhasil dibuat dan masuk ke Tabel Loket Penunjang`,
patient: newPatient,
};
};
const changeKlinik = (patient, newKlinik, adminType = 'loket') => {
const patientIndex = allPatients.value.findIndex((p) => p.no === patient.no);
if (patientIndex !== -1) {
allPatients.value[patientIndex].klinik = newKlinik.name;
// Update current processing if it's the same patient
if (currentProcessingPatient.value[adminType]?.no === patient.no) {
currentProcessingPatient.value[adminType].klinik = newKlinik.name;
}
return {
success: true,
message: `Klinik berhasil diubah ke ${newKlinik.name}`,
};
}
return { success: false, message: "Pasien tidak ditemukan" };
};
const getCurrentProcessing = (adminType) => {
return computed(() => currentProcessingPatient.value[adminType]);
};
const setCurrentProcessing = (patient, adminType) => {
currentProcessingPatient.value[adminType] = patient;
};
return {
// State
allPatients,
quotaUsed,
currentProcessingPatient,
kliniks,
penunjangs,
// Computed
totalPasien,
// Actions
callNext,
callMultiplePatients,
processPatient,
createAntreanKlinik,
createAntreanPenunjang,
changeKlinik,
getPatientsByStage,
getTotalPasienByStage,
getCurrentProcessing,
setCurrentProcessing,
};
});