368 lines
9.4 KiB
JavaScript
368 lines
9.4 KiB
JavaScript
// stores/ruangStore.js
|
|
// Merged dari masterStore.ruangData + klinikruangstore.klinikRuangList
|
|
import { defineStore } from 'pinia';
|
|
import { ref, computed } from 'vue';
|
|
import { useClinicStore } from './clinicStore';
|
|
|
|
export const useRuangStore = defineStore('ruang', () => {
|
|
const clinicStore = useClinicStore();
|
|
|
|
// State/Computed - List Master Klinik (disinkronkan dengan clinicStore)
|
|
const masterKlinikList = computed(() => {
|
|
const baseList = typeof clinicStore.getClinicsForDropdown === 'function'
|
|
? clinicStore.getClinicsForDropdown()
|
|
: [];
|
|
|
|
return baseList.map((c) => ({
|
|
kode: c.kode,
|
|
nama: c.name,
|
|
id: c.id,
|
|
}));
|
|
});
|
|
|
|
// State - Ruang Data (merged dari masterStore.ruangData + klinikruangstore.klinikRuangList)
|
|
const ruangData = ref([
|
|
{
|
|
id: 1,
|
|
no: 1,
|
|
kodeKlinik: 'AN',
|
|
namaKlinik: 'ANAK',
|
|
namaRuang: 'R. TINDAKAN',
|
|
ruangList: [
|
|
{ nomorRuang: '1', namaRuang: 'R. TINDAKAN', nomorScreen: '101' }
|
|
]
|
|
},
|
|
{
|
|
id: 2,
|
|
no: 2,
|
|
kodeKlinik: 'AS',
|
|
namaKlinik: 'ANESTESI',
|
|
namaRuang: 'Ruang 1, Ruang 2, Ruang 3, Ruang 4, Ruang 5, Ruang 6',
|
|
ruangList: [
|
|
{ nomorRuang: '1', namaRuang: 'Ruang 1', nomorScreen: '201' },
|
|
{ nomorRuang: '2', namaRuang: 'Ruang 2', nomorScreen: '202' },
|
|
{ nomorRuang: '3', namaRuang: 'Ruang 3', nomorScreen: '203' },
|
|
{ nomorRuang: '4', namaRuang: 'Ruang 4', nomorScreen: '204' },
|
|
{ nomorRuang: '5', namaRuang: 'Ruang 5', nomorScreen: '205' },
|
|
{ nomorRuang: '6', namaRuang: 'Ruang 6', nomorScreen: '206' }
|
|
]
|
|
},
|
|
{
|
|
id: 3,
|
|
no: 3,
|
|
kodeKlinik: 'BD',
|
|
namaKlinik: 'BEDAH',
|
|
namaRuang: 'Ruang Konsultasi',
|
|
ruangList: [
|
|
{ nomorRuang: '1', namaRuang: 'Ruang Konsultasi', nomorScreen: '301' }
|
|
]
|
|
},
|
|
{
|
|
id: 4,
|
|
no: 4,
|
|
kodeKlinik: 'GR',
|
|
namaKlinik: 'GERIATRI',
|
|
namaRuang: 'Ruang Pemeriksaan',
|
|
ruangList: [
|
|
{ nomorRuang: '1', namaRuang: 'Ruang Pemeriksaan', nomorScreen: '401' }
|
|
]
|
|
},
|
|
{
|
|
id: 5,
|
|
no: 5,
|
|
kodeKlinik: 'GI',
|
|
namaKlinik: 'GIGI DAN MULUT',
|
|
namaRuang: 'Ruang 1, Ruang 2, Ruang 3',
|
|
ruangList: [
|
|
{ nomorRuang: '1', namaRuang: 'Ruang 1', nomorScreen: '501' },
|
|
{ nomorRuang: '2', namaRuang: 'Ruang 2', nomorScreen: '502' },
|
|
{ nomorRuang: '3', namaRuang: 'Ruang 3', nomorScreen: '503' }
|
|
]
|
|
},
|
|
]);
|
|
|
|
// Computed
|
|
const totalKlinikRuang = computed(() => ruangData.value.length);
|
|
|
|
const totalRuangan = computed(() => {
|
|
return ruangData.value.reduce((total, klinik) => {
|
|
return total + klinik.ruangList.length;
|
|
}, 0);
|
|
});
|
|
|
|
// Get all ruang list (for antrian display)
|
|
const getAllRuangList = computed(() => {
|
|
const allRuang = [];
|
|
ruangData.value.forEach(klinik => {
|
|
klinik.ruangList.forEach(ruang => {
|
|
allRuang.push({
|
|
kodeKlinik: klinik.kodeKlinik,
|
|
namaKlinik: klinik.namaKlinik,
|
|
...ruang
|
|
});
|
|
});
|
|
});
|
|
return allRuang;
|
|
});
|
|
|
|
// Getters
|
|
const getKlinikByCode = (kode) => {
|
|
return ruangData.value.find(k => k.kodeKlinik === kode);
|
|
};
|
|
|
|
const getRuangByKlinik = (kodeKlinik) => {
|
|
return ruangData.value.filter(r => r.kodeKlinik === kodeKlinik);
|
|
};
|
|
|
|
// Actions - CRUD Operations
|
|
const createKlinikRuang = (data) => {
|
|
const newId = Math.max(...ruangData.value.map(r => r.id), 0) + 1;
|
|
const newNo = ruangData.value.length + 1;
|
|
|
|
// Generate nama ruang untuk display
|
|
const namaRuangDisplay = data.ruangList
|
|
.map(r => r.namaRuang)
|
|
.filter(n => n)
|
|
.join(', ');
|
|
|
|
const newKlinikRuang = {
|
|
id: newId,
|
|
no: newNo,
|
|
kodeKlinik: data.kodeKlinik,
|
|
namaKlinik: data.namaKlinik,
|
|
namaRuang: namaRuangDisplay,
|
|
ruangList: data.ruangList
|
|
};
|
|
|
|
ruangData.value.push(newKlinikRuang);
|
|
|
|
return {
|
|
success: true,
|
|
message: `Klinik Ruang ${data.namaKlinik} berhasil ditambahkan`,
|
|
data: newKlinikRuang
|
|
};
|
|
};
|
|
|
|
const updateKlinikRuang = (id, data) => {
|
|
const index = ruangData.value.findIndex(r => r.id === id);
|
|
|
|
if (index === -1) {
|
|
return {
|
|
success: false,
|
|
message: 'Klinik Ruang tidak ditemukan'
|
|
};
|
|
}
|
|
|
|
// Generate nama ruang untuk display
|
|
const namaRuangDisplay = data.ruangList
|
|
.map(r => r.namaRuang)
|
|
.filter(n => n)
|
|
.join(', ');
|
|
|
|
ruangData.value[index] = {
|
|
...ruangData.value[index],
|
|
kodeKlinik: data.kodeKlinik,
|
|
namaKlinik: data.namaKlinik,
|
|
namaRuang: namaRuangDisplay,
|
|
ruangList: data.ruangList
|
|
};
|
|
|
|
return {
|
|
success: true,
|
|
message: `Klinik Ruang ${data.namaKlinik} berhasil diupdate`,
|
|
data: ruangData.value[index]
|
|
};
|
|
};
|
|
|
|
const deleteKlinikRuang = (id) => {
|
|
const index = ruangData.value.findIndex(r => r.id === id);
|
|
|
|
if (index === -1) {
|
|
return {
|
|
success: false,
|
|
message: 'Klinik Ruang tidak ditemukan'
|
|
};
|
|
}
|
|
|
|
const deletedKlinik = ruangData.value[index];
|
|
ruangData.value.splice(index, 1);
|
|
|
|
// Reorder numbers
|
|
ruangData.value.forEach((r, idx) => {
|
|
r.no = idx + 1;
|
|
});
|
|
|
|
return {
|
|
success: true,
|
|
message: `Klinik Ruang ${deletedKlinik.namaKlinik} berhasil dihapus`
|
|
};
|
|
};
|
|
|
|
const addRuangToKlinik = (klinikId, ruangDataItem) => {
|
|
const klinik = ruangData.value.find(k => k.id === klinikId);
|
|
|
|
if (!klinik) {
|
|
return {
|
|
success: false,
|
|
message: 'Klinik tidak ditemukan'
|
|
};
|
|
}
|
|
|
|
klinik.ruangList.push(ruangDataItem);
|
|
|
|
// Update display name
|
|
klinik.namaRuang = klinik.ruangList
|
|
.map(r => r.namaRuang)
|
|
.filter(n => n)
|
|
.join(', ');
|
|
|
|
return {
|
|
success: true,
|
|
message: `Ruang ${ruangDataItem.namaRuang} berhasil ditambahkan`,
|
|
data: klinik
|
|
};
|
|
};
|
|
|
|
const removeRuangFromKlinik = (klinikId, ruangIndex) => {
|
|
const klinik = ruangData.value.find(k => k.id === klinikId);
|
|
|
|
if (!klinik) {
|
|
return {
|
|
success: false,
|
|
message: 'Klinik tidak ditemukan'
|
|
};
|
|
}
|
|
|
|
if (klinik.ruangList.length <= 1) {
|
|
return {
|
|
success: false,
|
|
message: 'Minimal harus ada 1 ruangan'
|
|
};
|
|
}
|
|
|
|
const removedRuang = klinik.ruangList[ruangIndex];
|
|
klinik.ruangList.splice(ruangIndex, 1);
|
|
|
|
// Update display name
|
|
klinik.namaRuang = klinik.ruangList
|
|
.map(r => r.namaRuang)
|
|
.filter(n => n)
|
|
.join(', ');
|
|
|
|
return {
|
|
success: true,
|
|
message: `Ruang ${removedRuang.namaRuang} berhasil dihapus`,
|
|
data: klinik
|
|
};
|
|
};
|
|
|
|
const searchKlinikRuang = (searchTerm) => {
|
|
if (!searchTerm) return ruangData.value;
|
|
|
|
const term = searchTerm.toLowerCase();
|
|
return ruangData.value.filter(k =>
|
|
k.kodeKlinik.toLowerCase().includes(term) ||
|
|
k.namaKlinik.toLowerCase().includes(term) ||
|
|
k.namaRuang.toLowerCase().includes(term)
|
|
);
|
|
};
|
|
|
|
// Alias methods untuk backward compatibility dengan masterStore
|
|
const addRuang = (ruangPayload) => {
|
|
return createKlinikRuang(ruangPayload);
|
|
};
|
|
|
|
const updateRuang = (ruangPayload) => {
|
|
return updateKlinikRuang(ruangPayload.id, ruangPayload);
|
|
};
|
|
|
|
const deleteRuang = (ruangId) => {
|
|
return deleteKlinikRuang(ruangId);
|
|
};
|
|
|
|
// New method for replacing all rooms (used by MasterKlinikRuang when generating from API)
|
|
const replaceAllRooms = (newRoomsData) => {
|
|
// Group rooms by clinic CODE + JENIS LAYANAN (to keep Reguler and Eksekutif separate)
|
|
const groupedByClinic = {};
|
|
|
|
newRoomsData.forEach(room => {
|
|
// Use kodeKlinik + jenisLayanan as key to separate same clinic with different service types
|
|
const key = `${room.kodeKlinik}-${room.jenisLayanan}`;
|
|
|
|
if (!groupedByClinic[key]) {
|
|
groupedByClinic[key] = {
|
|
id: room.id || generateRoomId(),
|
|
kodeKlinik: room.kodeKlinik,
|
|
namaKlinik: room.namaKlinik,
|
|
jenisLayanan: room.jenisLayanan,
|
|
ruangList: []
|
|
};
|
|
}
|
|
|
|
groupedByClinic[key].ruangList.push({
|
|
nomorRuang: room.nomorRuang,
|
|
namaRuang: room.namaRuang,
|
|
nomorScreen: room.nomorScreen,
|
|
kodeRuang: room.kodeRuang
|
|
});
|
|
});
|
|
|
|
// Convert to array and add display names
|
|
const newRuangData = Object.values(groupedByClinic).map((clinic, index) => ({
|
|
...clinic,
|
|
no: index + 1,
|
|
namaRuang: clinic.ruangList.map(r => r.namaRuang).join(', ')
|
|
}));
|
|
|
|
ruangData.value = newRuangData;
|
|
|
|
return {
|
|
success: true,
|
|
message: `${newRuangData.length} klinik dengan total ${newRoomsData.length} ruangan berhasil dimuat`
|
|
};
|
|
};
|
|
|
|
// Helper to generate unique room ID
|
|
const generateRoomId = () => {
|
|
return Date.now() + Math.floor(Math.random() * 1000);
|
|
};
|
|
|
|
return {
|
|
// State
|
|
masterKlinikList,
|
|
ruangData,
|
|
|
|
// Computed
|
|
totalKlinikRuang,
|
|
totalRuangan,
|
|
getAllRuangList,
|
|
|
|
// Getters
|
|
getKlinikByCode,
|
|
getRuangByKlinik,
|
|
|
|
// Actions (new names)
|
|
createKlinikRuang,
|
|
updateKlinikRuang,
|
|
deleteKlinikRuang,
|
|
addRuangToKlinik,
|
|
removeRuangFromKlinik,
|
|
searchKlinikRuang,
|
|
|
|
// Alias for backward compatibility
|
|
addRuang,
|
|
updateRuang,
|
|
deleteRuang,
|
|
|
|
// New method for API-based room generation
|
|
replaceAllRooms,
|
|
};
|
|
}, {
|
|
persist: {
|
|
key: 'ruang-store-state',
|
|
storage: typeof window !== 'undefined' ? localStorage : undefined,
|
|
paths: ['ruangData'],
|
|
},
|
|
});
|
|
|