Files
simrsx-fe/app/handlers/integration-sep-list.handler.ts

285 lines
8.3 KiB
TypeScript

import { ref, reactive } from 'vue'
// Components
import { toast } from '~/components/pub/ui/toast'
// Types
import type { Ref as VueRef } from 'vue'
import type { DateRange } from 'radix-vue'
import type { DataTableLoader } from '~/components/pub/my-ui/data-table/type'
import type { HeaderPrep, RefSearchNav } from '~/components/pub/my-ui/data/types'
import type { PaginationMeta } from '~/components/pub/my-ui/pagination/pagination.type'
import type { VclaimSepData } from '~/models/vclaim'
// Libraries
import { CalendarDate, getLocalTimeZone } from '@internationalized/date'
import { getFormatDateId } from '~/lib/date'
import { downloadCsv, downloadXls } from '~/lib/download'
import { serviceTypes } from '~/lib/constants.vclaim'
import { getList as geMonitoringVisitList } from '~/services/vclaim-monitoring-visit.service'
import { remove as removeSepData, makeSepDataForRemove } from '~/services/vclaim-sep.service'
const headerKeys = [
'letterDate',
'letterNumber',
'serviceType',
'flow',
'medicalRecordNumber',
'patientName',
'cardNumber',
'controlLetterNumber',
'controlLetterDate',
'clinicDestination',
'attendingDoctor',
'diagnosis',
'careClass',
]
const headerLabels = [
'Tanggal SEP',
'No. SEP',
'Jenis Pelayanan',
'Alur',
'No. Rekam Medis',
'Nama Pasien',
'No. Kartu BPJS',
'No. Surat Kontrol',
'Tgl Surat Kontrol',
'Poli Tujuan',
'Dokter Penanggung Jawab',
'Diagnosa',
'Kelas Perawatan',
]
export function useIntegrationSepList() {
const userStore = useUserStore()
const today = new Date()
const initCalDate = (d: Date) => new CalendarDate(d.getFullYear(), d.getMonth() + 1, d.getDate())
const recId = ref<number>(0)
const recAction = ref<string>('')
const recItem = ref<any>(null)
const data = ref<VclaimSepData[]>([])
const dateSelection = ref({ start: initCalDate(today), end: initCalDate(today) }) as VueRef<DateRange>
const dateRange = ref(`${getFormatDateId(today)} - ${getFormatDateId(today)}`)
const serviceType = ref('2')
const serviceTypesList = ref<any[]>([])
const search = ref('')
const open = ref(false)
const sepData = ref({
sepNumber: '',
cardNumber: '',
patientName: '',
})
const refSearchNav: RefSearchNav = {
onClick: () => {},
onInput: (_val: string) => {},
onClear: () => {},
}
const headerPrep: HeaderPrep = {
title: 'Daftar SEP Prosedur',
icon: 'i-lucide-panel-bottom',
addNav: {
label: 'Tambah',
onClick: () => {
navigateTo('/integration/bpjs-vclaim/sep/add')
},
},
}
const paginationMeta = reactive<PaginationMeta>({
recordCount: 0,
page: 1,
pageSize: 10,
totalPage: 5,
hasNext: false,
hasPrev: false,
})
const isLoading = reactive<DataTableLoader>({
isTableLoading: false,
})
const getDateFilter = () => {
let dateFilter = ''
const isTimeLocal = true
const dateFirst =
dateSelection.value && dateSelection.value.start
? dateSelection.value.start.toDate(getLocalTimeZone())
: new Date()
if (isTimeLocal && dateSelection.value && dateSelection.value.end) {
const { year, month, day } = dateSelection.value.end
dateFilter = `${year}-${month}-${day}`
} else {
dateFilter = dateFirst.toISOString().substring(0, 10)
}
return dateFilter
}
const getMonitoringVisitMappers = async () => {
isLoading.dataListLoading = true
data.value = []
const dateFilter = getDateFilter()
const result = await geMonitoringVisitList({
date: dateFilter || '',
serviceType: serviceType.value,
})
if (result && result.success && result.body) {
const visitsRaw = result.body?.response?.sep || []
if (!visitsRaw) {
isLoading.dataListLoading = false
return
}
visitsRaw.forEach((result: any) => {
let st = result.jnsPelayanan || '-'
if (st === 'R.Inap') st = 'Rawat Inap'
else if (st === '1' || st === 'R.Jalan') st = 'Rawat Jalan'
data.value.push({
letterDate: result.tglSep || '-',
letterNumber: result.noSep || '-',
serviceType: st,
flow: '-',
medicalRecordNumber: '-',
patientName: result.nama || '-',
cardNumber: result.noKartu || '-',
controlLetterNumber: result.noRujukan || '-',
controlLetterDate: result.tglPlgSep || '-',
clinicDestination: result.poli || '-',
attendingDoctor: '-',
diagnosis: result.diagnosa || '-',
careClass: result.kelasRawat || '-',
})
})
}
isLoading.dataListLoading = false
}
const getSepList = async () => {
await getMonitoringVisitMappers()
}
const setServiceTypes = () => {
serviceTypesList.value = Object.keys(serviceTypes).map((item) => ({
value: item.toString(),
label: serviceTypes[item],
})) as any
}
const setDateRange = () => {
const startCal = dateSelection.value.start
const endCal = dateSelection.value.end
const s = startCal ? startCal.toDate(getLocalTimeZone()) : today
const e = endCal ? endCal.toDate(getLocalTimeZone()) : today
dateRange.value = `${getFormatDateId(s)} - ${getFormatDateId(e)}`
}
const handleExportCsv = () => {
if (!data.value || data.value.length === 0) {
toast({ title: 'Kosong', description: 'Tidak ada data untuk diekspor', variant: 'destructive' })
return
}
const yyyy = today.getFullYear()
const mm = String(today.getMonth() + 1).padStart(2, '0')
const dd = String(today.getDate()).padStart(2, '0')
const dateStr = `${yyyy}-${mm}-${dd}`
const filename = `file-sep-${dateStr}.csv`
downloadCsv(headerKeys, headerLabels, data.value, filename, ',', true)
}
const handleExportExcel = async () => {
if (!data.value || data.value.length === 0) {
toast({ title: 'Kosong', description: 'Tidak ada data untuk diekspor', variant: 'destructive' })
return
}
const yyyy = today.getFullYear()
const mm = String(today.getMonth() + 1).padStart(2, '0')
const dd = String(today.getDate()).padStart(2, '0')
const dateStr = `${yyyy}-${mm}-${dd}`
const filename = `file-sep-${dateStr}.xlsx`
try {
await downloadXls(headerKeys, headerLabels, data.value, filename, 'SEP Data')
} catch (err: any) {
console.error('exportExcel error', err)
toast({ title: 'Gagal', description: err?.message || 'Gagal mengekspor data ke Excel', variant: 'destructive' })
}
}
const handleRowSelected = (row: any) => {
if (!row) return
sepData.value.sepNumber = row.letterNumber || ''
sepData.value.cardNumber = row.cardNumber || ''
sepData.value.patientName = row.patientName || ''
recItem.value = row
recId.value = (row && (row.id || row.recId)) || 0
}
const handlePageChange = (page: number) => {
console.log('pageChange', page)
}
const handleRemove = async () => {
try {
const result = await removeSepData(
makeSepDataForRemove({ ...sepData.value, userName: userStore.user?.user_name }),
)
const backendMessage = result?.body?.message || result?.message || null
const backendStatus = result?.body?.status || result?.status || null
if (
backendMessage === 'success' ||
(backendStatus === 'error' && backendMessage === 'Decrypt failed: illegal base64 data at input byte 16')
) {
await getSepList()
toast({ title: 'Berhasil', description: backendMessage || 'Data berhasil dihapus', variant: 'default' })
} else {
toast({ title: 'Gagal', description: backendMessage || 'Gagal menghapus data', variant: 'destructive' })
}
} catch (err: any) {
console.error('handleRemove error', err)
toast({
title: 'Gagal',
description: err?.message || 'Terjadi kesalahan saat menghapus data',
variant: 'destructive',
})
} finally {
recId.value = 0
recAction.value = ''
open.value = false
}
}
return {
recId,
recAction,
recItem,
data,
dateSelection,
dateRange,
serviceType,
serviceTypesList,
search,
open,
sepData,
headerPrep,
refSearchNav,
paginationMeta,
isLoading,
getSepList,
setServiceTypes,
setDateRange,
handleExportCsv,
handleExportExcel,
handleRowSelected,
handlePageChange,
handleRemove,
}
}
export default useIntegrationSepList