Merge branch 'dev' into feat/procedure-room-order
This commit is contained in:
No files matched your search
@@ -0,0 +1,24 @@
|
||||
// Handlers
|
||||
import { genCrudHandler } from '~/handlers/_handler'
|
||||
|
||||
// Services
|
||||
import { create, update, remove } from '~/services/antibiotic-in-use'
|
||||
|
||||
export const {
|
||||
recId,
|
||||
recAction,
|
||||
recItem,
|
||||
isReadonly,
|
||||
isProcessing,
|
||||
isFormEntryDialogOpen,
|
||||
isRecordConfirmationOpen,
|
||||
onResetState,
|
||||
handleActionSave,
|
||||
handleActionEdit,
|
||||
handleActionRemove,
|
||||
handleCancelForm,
|
||||
} = genCrudHandler({
|
||||
create,
|
||||
update,
|
||||
remove,
|
||||
})
|
||||
@@ -0,0 +1,24 @@
|
||||
// Handlers
|
||||
import { genCrudHandler } from '~/handlers/_handler'
|
||||
|
||||
// Services
|
||||
import { create, update, remove } from '~/services/antibiotic-src-category'
|
||||
|
||||
export const {
|
||||
recId,
|
||||
recAction,
|
||||
recItem,
|
||||
isReadonly,
|
||||
isProcessing,
|
||||
isFormEntryDialogOpen,
|
||||
isRecordConfirmationOpen,
|
||||
onResetState,
|
||||
handleActionSave,
|
||||
handleActionEdit,
|
||||
handleActionRemove,
|
||||
handleCancelForm,
|
||||
} = genCrudHandler({
|
||||
create,
|
||||
update,
|
||||
remove,
|
||||
})
|
||||
@@ -0,0 +1,24 @@
|
||||
// Handlers
|
||||
import { genCrudHandler } from '~/handlers/_handler'
|
||||
|
||||
// Services
|
||||
import { create, update, remove } from '~/services/antibiotic-src'
|
||||
|
||||
export const {
|
||||
recId,
|
||||
recAction,
|
||||
recItem,
|
||||
isReadonly,
|
||||
isProcessing,
|
||||
isFormEntryDialogOpen,
|
||||
isRecordConfirmationOpen,
|
||||
onResetState,
|
||||
handleActionSave,
|
||||
handleActionEdit,
|
||||
handleActionRemove,
|
||||
handleCancelForm,
|
||||
} = genCrudHandler({
|
||||
create,
|
||||
update,
|
||||
remove,
|
||||
})
|
||||
@@ -8,6 +8,7 @@ import { toast } from '~/components/pub/ui/toast'
|
||||
import type { TreeItem } from '~/components/pub/my-ui/select-tree/type'
|
||||
import type { DataTableLoader } from '~/components/pub/my-ui/data-table/type'
|
||||
import { paymentTypes, sepRefTypeCodes, participantGroups } from '~/lib/constants.vclaim'
|
||||
import { genDoctor, type Doctor } from '~/models/doctor'
|
||||
|
||||
// Stores
|
||||
import { useUserStore } from '~/stores/user'
|
||||
@@ -17,13 +18,15 @@ import {
|
||||
getList as getSpecialistList,
|
||||
getValueTreeItems as getSpecialistTreeItems,
|
||||
} from '~/services/specialist.service'
|
||||
import { getValueLabelList as getDoctorValueLabelList } from '~/services/doctor.service'
|
||||
import { getDetail as getDoctorDetail, getValueLabelList as getDoctorValueLabelList } from '~/services/doctor.service'
|
||||
import {
|
||||
create as createEncounter,
|
||||
getDetail as getEncounterDetail,
|
||||
update as updateEncounter,
|
||||
} from '~/services/encounter.service'
|
||||
import { getList as getMemberList } from '~/services/vclaim-member.service'
|
||||
import { getList as getSepList } from '~/services/vclaim-sep.service'
|
||||
import { uploadAttachment } from '~/services/supporting-document.service'
|
||||
|
||||
// Handlers
|
||||
import {
|
||||
@@ -59,12 +62,14 @@ export function useEncounterEntry(props: {
|
||||
const encounterData = ref<any>(null)
|
||||
const formObjects = ref<any>({})
|
||||
const isSepValid = ref(false)
|
||||
const isMemberValid = ref(false)
|
||||
const isCheckingSep = ref(false)
|
||||
const sepNumber = ref('')
|
||||
const vclaimReference = ref<any>(null)
|
||||
|
||||
const sepFile = ref<File | null>(null)
|
||||
const sippFile = ref<File | null>(null)
|
||||
const selectedDoctor = ref<Doctor>(genDoctor())
|
||||
const isEditMode = computed(() => props.id > 0)
|
||||
|
||||
const isSaveDisabled = computed(() => {
|
||||
return !selectedPatient.value || !selectedPatientObject.value || isSaving.value || isLoadingDetail.value
|
||||
})
|
||||
@@ -73,15 +78,12 @@ export function useEncounterEntry(props: {
|
||||
if (props.classCode === 'ambulatory') {
|
||||
return '/ambulatory/encounter'
|
||||
}
|
||||
// if (props.classCode === 'ambulatory' && props.subClassCode === 'reg') {
|
||||
// return '/outpatient/encounter'
|
||||
// }
|
||||
// if (props.classCode === 'emergency') {
|
||||
// return '/emergency/encounter'
|
||||
// }
|
||||
// if (props.classCode === 'inpatient') {
|
||||
// return '/inpatient/encounter'
|
||||
// }
|
||||
if (props.classCode === 'emergency') {
|
||||
return '/emergency/encounter'
|
||||
}
|
||||
if (props.classCode === 'inpatient') {
|
||||
return '/inpatient/encounter'
|
||||
}
|
||||
return '/encounter'
|
||||
}
|
||||
|
||||
@@ -201,6 +203,34 @@ export function useEncounterEntry(props: {
|
||||
return { specialist_id: null, subspecialist_id: null }
|
||||
}
|
||||
|
||||
async function getDoctorInfo(value: string) {
|
||||
const resp = await getDoctorDetail(value, { includes: 'unit,specialist,subspecialist' })
|
||||
if (resp.success) {
|
||||
selectedDoctor.value = resp.body.data
|
||||
}
|
||||
}
|
||||
|
||||
async function getValidateMember(member: string) {
|
||||
if (isCheckingSep.value) return
|
||||
isMemberValid.value = false
|
||||
try {
|
||||
const result = await getMemberList({
|
||||
mode: 'by-card',
|
||||
number: member,
|
||||
date: new Date().toISOString().split('T')[0],
|
||||
})
|
||||
if (result.success && result.body?.response !== null) {
|
||||
const response = result.body?.response || {}
|
||||
if (Object.keys(response).length > 0) {
|
||||
formObjects.value.nationalIdentity = response.peserta?.nik || ''
|
||||
}
|
||||
isMemberValid.value = result.body?.metaData?.code === '200'
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error checking member:', error)
|
||||
}
|
||||
}
|
||||
|
||||
async function getValidateSepNumber(sepNumberValue: string) {
|
||||
vclaimReference.value = null
|
||||
if (!sepNumberValue || sepNumberValue.trim() === '') {
|
||||
@@ -220,19 +250,25 @@ export function useEncounterEntry(props: {
|
||||
formObjects.value.medicalRecordNumber = response.peserta?.noMr || '-'
|
||||
formObjects.value.cardNumber = response.peserta?.noKartu || '-'
|
||||
formObjects.value.registerDate = response.tglSep || null
|
||||
formObjects.value.sepReference = response.noSep || '-'
|
||||
formObjects.value.sepControlDate = response.tglSep || null
|
||||
formObjects.value.sepTrafficStatus = response.nmstatusKecelakaan || '-'
|
||||
formObjects.value.diagnosis = response.diagnosa || '-'
|
||||
vclaimReference.value = {
|
||||
noSep: response.noSep || sepNumberValue.trim(),
|
||||
tglRujukan: response.tglSep ? new Date(response.tglSep).toISOString() : null,
|
||||
ppkDirujuk: response.noRujukan || 'rssa',
|
||||
jnsPelayanan: response.jnsPelayanan === 'Rawat Jalan' ? '2' : response.jnsPelayanan === 'Rawat Inap' ? '1' : null,
|
||||
jnsPelayanan:
|
||||
response.jnsPelayanan === 'Rawat Jalan' ? '2' : response.jnsPelayanan === 'Rawat Inap' ? '1' : null,
|
||||
catatan: response.catatan || '',
|
||||
diagRujukan: response.diagnosa || '',
|
||||
tipeRujukan: response.tujuanKunj?.kode ?? '0',
|
||||
poliRujukan: response.poli || '',
|
||||
user: '',
|
||||
user: userStore.user?.user_name || '',
|
||||
}
|
||||
}
|
||||
isSepValid.value = result.body?.metaData?.code === '200'
|
||||
isMemberValid.value = isSepValid.value
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error checking SEP:', error)
|
||||
@@ -305,7 +341,7 @@ export function useEncounterEntry(props: {
|
||||
}
|
||||
}
|
||||
|
||||
async function loadEncounterDetail() {
|
||||
async function getFetchEncounterDetail() {
|
||||
if (!isEditMode.value || props.id <= 0) {
|
||||
return
|
||||
}
|
||||
@@ -313,22 +349,23 @@ export function useEncounterEntry(props: {
|
||||
try {
|
||||
isLoadingDetail.value = true
|
||||
const result = await getEncounterDetail(props.id, {
|
||||
includes: 'patient,patient-person,specialist,subspecialist',
|
||||
includes: 'patient,patient-person,specialist,subspecialist,Appointment_Doctor,EncounterDocuments',
|
||||
})
|
||||
|
||||
if (result.success && result.body?.data) {
|
||||
encounterData.value = result.body.data
|
||||
await mapEncounterToForm(encounterData.value)
|
||||
isLoadingDetail.value = false
|
||||
} else {
|
||||
const errorMsg = result.body?.message || 'Gagal memuat data kunjungan'
|
||||
toast({
|
||||
title: 'Gagal',
|
||||
description: 'Gagal memuat data kunjungan',
|
||||
description: errorMsg,
|
||||
variant: 'destructive',
|
||||
})
|
||||
await navigateTo(getListPath())
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('Error loading encounter detail:', error)
|
||||
toast({
|
||||
title: 'Gagal',
|
||||
description: error?.message || 'Gagal memuat data kunjungan',
|
||||
@@ -362,9 +399,10 @@ export function useEncounterEntry(props: {
|
||||
formData.medicalRecordNumber = selectedPatientObject.value.number || ''
|
||||
}
|
||||
|
||||
const doctorId = encounter.appointment_doctor_id || encounter.responsible_doctor_id
|
||||
if (doctorId) {
|
||||
formData.doctorId = String(doctorId)
|
||||
const doctorCode = encounter.appointment_doctor_code || encounter.responsible_doctor_code
|
||||
if (doctorCode) {
|
||||
formData.doctorCode = String(doctorCode)
|
||||
await getDoctorInfo(doctorCode)
|
||||
}
|
||||
|
||||
if (encounter.subspecialist_id) {
|
||||
@@ -390,12 +428,14 @@ export function useEncounterEntry(props: {
|
||||
if (encounter.registeredAt) {
|
||||
const date = new Date(encounter.registeredAt)
|
||||
formData.registerDate = date.toISOString().split('T')[0]
|
||||
} else if (encounter.visitDate) {
|
||||
}
|
||||
if (encounter.visitDate) {
|
||||
const date = new Date(encounter.visitDate)
|
||||
formData.registerDate = date.toISOString().split('T')[0]
|
||||
}
|
||||
|
||||
if (encounter.paymentMethod_code) {
|
||||
formData.paymentMethodCode = encounter.paymentMethod_code
|
||||
if (encounter.paymentMethod_code === 'insurance') {
|
||||
formData.paymentType = 'jkn'
|
||||
} else {
|
||||
@@ -412,7 +452,15 @@ export function useEncounterEntry(props: {
|
||||
|
||||
formData.cardNumber = encounter.member_number || ''
|
||||
formData.sepNumber = encounter.ref_number || ''
|
||||
formObjects.value = formData
|
||||
formData.sepType = encounter.sep_type || ''
|
||||
formData.patientCategory = encounter.participant_group_code || ''
|
||||
|
||||
// Map BPJS reference data if available
|
||||
if (encounter.vclaimReference) {
|
||||
formData.sepReference = encounter.vclaimReference?.noSep || ''
|
||||
} else if (encounter.ref_number) {
|
||||
formData.sepReference = encounter.ref_number
|
||||
}
|
||||
|
||||
if (formData.sepNumber) {
|
||||
sepNumber.value = formData.sepNumber
|
||||
@@ -420,6 +468,8 @@ export function useEncounterEntry(props: {
|
||||
if (formData.subSpecialistId) {
|
||||
await handleFetchDoctors(formData.subSpecialistId)
|
||||
}
|
||||
|
||||
formObjects.value = { ...formData }
|
||||
}
|
||||
|
||||
async function handleSaveEncounter(formValues: any) {
|
||||
@@ -434,7 +484,7 @@ export function useEncounterEntry(props: {
|
||||
|
||||
try {
|
||||
isSaving.value = true
|
||||
|
||||
const isAdmin = false
|
||||
const employeeId = userStore.user?.employee_id || userStore.user?.employee?.id || 0
|
||||
|
||||
const formatDate = (dateString: string): string => {
|
||||
@@ -499,19 +549,17 @@ export function useEncounterEntry(props: {
|
||||
if (paymentMethodCode === 'insurance') {
|
||||
payload.insuranceCompany_id = formValues.insuranceCompany_id ?? null
|
||||
if (memberNumber) payload.member_number = memberNumber
|
||||
if (refNumber) payload.ref_number = refNumber
|
||||
// if (refNumber) payload.ref_number = refNumber
|
||||
if (formValues.refTypeCode) payload.refTypeCode = formValues.refTypeCode
|
||||
if (formValues.vclaimReference) payload.vclaimReference = formValues.vclaimReference
|
||||
} else {
|
||||
if (paymentMethodCode === 'membership' && memberNumber) {
|
||||
payload.member_number = memberNumber
|
||||
}
|
||||
if (refNumber) {
|
||||
payload.ref_number = refNumber
|
||||
}
|
||||
// if (refNumber) payload.ref_number = refNumber
|
||||
}
|
||||
|
||||
if (props.classCode === 'ambulatory') {
|
||||
if (isAdmin && props.classCode === 'ambulatory') {
|
||||
payload.visitMode_code = 'adm'
|
||||
payload.allocatedVisitCount = 0
|
||||
}
|
||||
@@ -520,19 +568,35 @@ export function useEncounterEntry(props: {
|
||||
if (isEditMode.value) {
|
||||
result = await updateEncounter(props.id, payload)
|
||||
} else {
|
||||
console.log('💾 [ADD MODE] Sending POST request:', { payload })
|
||||
result = await createEncounter(payload)
|
||||
}
|
||||
|
||||
if (result.success) {
|
||||
console.log(result)
|
||||
console.log(sepFile.value)
|
||||
console.log(sippFile.value)
|
||||
// const encounterId = isEditMode.value ? props.id : result.body?.data?.id
|
||||
if (patientId) {
|
||||
if (sepFile.value) {
|
||||
await uploadAttachment(sepFile.value, patientId, 'vclaim-sep')
|
||||
}
|
||||
if (sippFile.value) {
|
||||
await uploadAttachment(sippFile.value, patientId, 'vclaim-sipp')
|
||||
}
|
||||
}
|
||||
|
||||
toast({
|
||||
title: 'Berhasil',
|
||||
description: isEditMode.value ? 'Kunjungan berhasil diperbarui' : 'Kunjungan berhasil dibuat',
|
||||
variant: 'default',
|
||||
})
|
||||
console.log('✅ [SAVE] Success - Redirecting to list page')
|
||||
await navigateTo(getListPath())
|
||||
} else {
|
||||
const errorMessage =
|
||||
result.body?.message || (isEditMode.value ? 'Gagal memperbarui kunjungan' : 'Gagal membuat kunjungan')
|
||||
console.error('❌ [SAVE] Failed:', errorMessage)
|
||||
toast({
|
||||
title: 'Gagal',
|
||||
description: errorMessage,
|
||||
@@ -540,7 +604,7 @@ export function useEncounterEntry(props: {
|
||||
})
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('Error saving encounter:', error)
|
||||
console.error('❌ [SAVE] Error saving encounter:', error)
|
||||
toast({
|
||||
title: 'Gagal',
|
||||
description: error?.message || (isEditMode.value ? 'Gagal memperbarui kunjungan' : 'Gagal membuat kunjungan'),
|
||||
@@ -556,6 +620,8 @@ export function useEncounterEntry(props: {
|
||||
paymentsList,
|
||||
sepsList,
|
||||
sepNumber,
|
||||
sepFile,
|
||||
sippFile,
|
||||
participantGroupsList,
|
||||
specialistsTree,
|
||||
doctorsList,
|
||||
@@ -565,15 +631,17 @@ export function useEncounterEntry(props: {
|
||||
encounterData,
|
||||
formObjects,
|
||||
openPatient,
|
||||
isMemberValid,
|
||||
isSepValid,
|
||||
isCheckingSep,
|
||||
isEditMode,
|
||||
isSaveDisabled,
|
||||
isLoading,
|
||||
selectedDoctor,
|
||||
selectedPatient,
|
||||
selectedPatientObject,
|
||||
paginationMeta,
|
||||
loadEncounterDetail,
|
||||
getFetchEncounterDetail,
|
||||
mapEncounterToForm,
|
||||
toKebabCase,
|
||||
toNavigateSep,
|
||||
@@ -585,6 +653,8 @@ export function useEncounterEntry(props: {
|
||||
getPatientsList,
|
||||
getPatientCurrent,
|
||||
getPatientByIdentifierSearch,
|
||||
getDoctorInfo,
|
||||
getValidateMember,
|
||||
getValidateSepNumber,
|
||||
handleFetchSpecialists,
|
||||
handleFetchDoctors,
|
||||
|
||||
@@ -41,6 +41,7 @@ const DeviceOrderAsync = defineAsyncComponent(() => import('~/components/content
|
||||
const PrescriptionAsync = defineAsyncComponent(() => import('~/components/content/prescription/main.vue'))
|
||||
const CpLabOrderAsync = defineAsyncComponent(() => import('~/components/content/cp-lab-order/main.vue'))
|
||||
const ProcedureRoomOrderAsync = defineAsyncComponent(() => import('~/components/content/procedure-room-order/main.vue'))
|
||||
const MicroLabOrderAsync = defineAsyncComponent(() => import('~/components/content/micro-lab-order/main.vue'))
|
||||
const CprjAsync = defineAsyncComponent(() => import('~/components/content/cprj/entry.vue'))
|
||||
const RadiologyAsync = defineAsyncComponent(() => import('~/components/content/radiology-order/main.vue'))
|
||||
const ConsultationAsync = defineAsyncComponent(() => import('~/components/content/consultation/list.vue'))
|
||||
@@ -48,6 +49,7 @@ const DocUploadListAsync = defineAsyncComponent(() => import('~/components/conte
|
||||
const GeneralConsentListAsync = defineAsyncComponent(() => import('~/components/content/general-consent/entry.vue'))
|
||||
const ResumeListAsync = defineAsyncComponent(() => import('~/components/content/resume/list.vue'))
|
||||
const ControlLetterListAsync = defineAsyncComponent(() => import('~/components/content/control-letter/list.vue'))
|
||||
const InitialNursingStudyAsync = defineAsyncComponent(() => import('~/components/content/initial-nursing/entry.vue'))
|
||||
|
||||
const defaultKeys: Record<string, any> = {
|
||||
status: {
|
||||
@@ -247,6 +249,12 @@ const defaultKeys: Record<string, any> = {
|
||||
classCode: ['ambulatory', 'emergency', 'inpatient'],
|
||||
unit: 'all',
|
||||
},
|
||||
initialNursingStudy: {
|
||||
id: 'initial-nursing-study',
|
||||
title: 'Kajian Awal Keperawatan',
|
||||
classCode: ['ambulatory', 'emergency', 'inpatient'],
|
||||
unit: 'all',
|
||||
},
|
||||
}
|
||||
|
||||
export function getItemsByClassCode(classCode: string, items: EncounterItem[]) {
|
||||
@@ -361,8 +369,7 @@ export function injectComponents(id: string | number, data: EncounterListData, m
|
||||
currentKeys.cpLabOrder['props'] = { encounter_id: id }
|
||||
}
|
||||
if (currentKeys?.microLabOrder) {
|
||||
// TODO: add component for microLabOrder
|
||||
currentKeys.microLabOrder['component'] = null
|
||||
currentKeys.microLabOrder['component'] = MicroLabOrderAsync
|
||||
currentKeys.microLabOrder['props'] = { encounter_id: id }
|
||||
}
|
||||
if (currentKeys?.paLabOrder) {
|
||||
@@ -406,6 +413,11 @@ export function injectComponents(id: string | number, data: EncounterListData, m
|
||||
currentKeys.priceList['props'] = { encounter_id: id }
|
||||
}
|
||||
|
||||
if (currentKeys?.initialNursingStudy) {
|
||||
currentKeys.initialNursingStudy['component'] = InitialNursingStudyAsync
|
||||
currentKeys.initialNursingStudy['props'] = { encounter: data?.encounter }
|
||||
}
|
||||
|
||||
return currentKeys
|
||||
}
|
||||
|
||||
@@ -485,13 +497,7 @@ export function mapResponseToEncounter(result: any): any {
|
||||
return mapped
|
||||
}
|
||||
|
||||
export function getMenuItems(
|
||||
id: string | number,
|
||||
props: any,
|
||||
user: any,
|
||||
data: EncounterListData,
|
||||
meta: any,
|
||||
) {
|
||||
export function getMenuItems(id: string | number, props: any, user: any, data: EncounterListData, meta: any) {
|
||||
console.log(props)
|
||||
// const normalClassCode = props.classCode === 'ambulatory' ? 'outpatient' : props.classCode
|
||||
const normalClassCode = props.classCode === 'ambulatory' ? 'ambulatory' : props.classCode
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
import { ref, computed } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { toast } from '~/components/pub/ui/toast'
|
||||
import { getList as getSepList } from '~/services/vclaim-sep.service'
|
||||
import { getList as getMemberList } from '~/services/vclaim-member.service'
|
||||
|
||||
export function useIntegrationSepDetail() {
|
||||
const route = useRoute()
|
||||
const isLoading = ref(false)
|
||||
const sepData = ref<any>(null)
|
||||
const valueObjects = ref<any>({})
|
||||
|
||||
const noSep = computed(() => {
|
||||
return typeof route.params.id === 'string' ? route.params.id : ''
|
||||
})
|
||||
|
||||
async function getSepDetail() {
|
||||
if (!noSep.value) {
|
||||
toast({
|
||||
title: 'Gagal',
|
||||
description: 'No SEP tidak ditemukan di URL',
|
||||
variant: 'destructive',
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
isLoading.value = true
|
||||
const result = await getSepList({ number: noSep.value })
|
||||
|
||||
if (result.success && result.body?.response) {
|
||||
const response = result.body.response
|
||||
sepData.value = response
|
||||
valueObjects.value = {
|
||||
sepNumber: response.noSep || noSep.value,
|
||||
eSep: response.eSEP === 'True' ? 'yes' : 'no',
|
||||
serviceType:
|
||||
response.jnsPelayanan === 'Rawat Jalan' ? '2' : response.jnsPelayanan === 'Rawat Inap' ? '1' : null,
|
||||
sepDate: response.tglSep ? new Date(response.tglSep).toISOString().split('T')[0] : '',
|
||||
cardNumber: response.peserta?.noKartu || '-',
|
||||
patientName: response.peserta?.nama || '-',
|
||||
phoneNumber: response.peserta?.noTelp || '-',
|
||||
medicalRecordNumber: response.peserta?.noMr || '-',
|
||||
memberInsurance: response.peserta?.asuransi || '-',
|
||||
memberClass: response.peserta?.hakKelas || '-',
|
||||
memberGender: response.peserta?.kelamin || '-',
|
||||
memberBirthDate: response.peserta?.tglLahir || '-',
|
||||
memberType: response.peserta?.jnsPeserta || '-',
|
||||
referralLetterNumber: response.noRujukan || '-',
|
||||
diagnosisName: response.diagnosa || '-',
|
||||
attendingDoctor: response.dpjp?.kdDPJP || '-',
|
||||
attendingDoctorName: response.dpjp?.nmDPJP || '-',
|
||||
polyName: response.poli || '-',
|
||||
cob: response.cob === '1' ? 'yes' : 'no',
|
||||
cataract: response.katarak === '1' ? 'yes' : 'no',
|
||||
clinicExcecutive: response.poliEksekutif === '1' ? 'yes' : 'no',
|
||||
procedureType: response.flagProcedure?.kode || '-',
|
||||
procedureTypeName: response.flagProcedure?.nama || '-',
|
||||
supportCode: response.kdPenunjang?.kode || '-',
|
||||
supportCodeName: response.kdPenunjang?.nama || '-',
|
||||
note: response.catatan || response.informasi || '-',
|
||||
classLevel: response.kelasRawat || '-',
|
||||
classLevelUpgrade: response.klsRawat?.klsRawatNaik || '-',
|
||||
classPaySource: response.klsRawat?.pembiayaan || '-',
|
||||
responsiblePerson: response.klsRawat?.penanggungJawab || response.penjamin || '-',
|
||||
purposeOfVisit: response.tujuanKunj?.kode || '-',
|
||||
purposeOfVisitName: response.tujuanKunj?.nama || '-',
|
||||
serviceAssessment: response.assestmenPel?.kode || '-',
|
||||
serviceAssessmentName: response.assestmenPel?.nama || '-',
|
||||
trafficAccident: response.kdStatusKecelakaan || '',
|
||||
trafficAccidentName: response.nmstatusKecelakaan || '',
|
||||
lpNumber: response.kontrol?.noSurat || '-',
|
||||
accidentDate: response.lokasiKejadian?.tglKejadian || '-',
|
||||
accidentNote: response.lokasiKejadian?.ketKejadian || '-',
|
||||
accidentProvince: response.lokasiKejadian?.kdProp || '-',
|
||||
accidentCity: response.lokasiKejadian?.kdKab || '-',
|
||||
accidentDistrict: response.lokasiKejadian?.kdKec || '-',
|
||||
accidentLocation: response.lokasiKejadian?.lokasi || '-',
|
||||
suplesi: response.jnsPelayanan === 'Rawat Jalan' ? 'yes' : 'no',
|
||||
suplesiNumber: response.jnsPelayanan === 'Rawat Jalan' ? response.noRujukan || '-' : '-',
|
||||
controlLetterNumber: response.kontrol?.noSurat || '-',
|
||||
controlLetterDoctor: response.kontrol?.kdDokter || '-',
|
||||
controlLetterDoctorName: response.kontrol?.nmDokter || '-',
|
||||
}
|
||||
if (valueObjects.value?.cardNumber !== '-') {
|
||||
const resultMember = await getMemberList({
|
||||
mode: 'by-card',
|
||||
number: valueObjects.value.cardNumber,
|
||||
date: new Date().toISOString().substring(0, 10),
|
||||
})
|
||||
if (resultMember && resultMember.success && resultMember.body) {
|
||||
const memberRaws = resultMember.body?.response || null
|
||||
valueObjects.value['nationalIdentity'] = memberRaws?.peserta?.nik || ''
|
||||
valueObjects.value['phoneNumber'] = memberRaws?.peserta?.mr?.noTelepon || ''
|
||||
valueObjects.value['classLevel'] = memberRaws?.peserta?.hakKelas?.kode || ''
|
||||
valueObjects.value['status'] = memberRaws?.statusPeserta?.kode || ''
|
||||
}
|
||||
}
|
||||
} else {
|
||||
toast({
|
||||
title: 'Gagal',
|
||||
description: 'Data SEP tidak ditemukan',
|
||||
variant: 'destructive',
|
||||
})
|
||||
await navigateTo('/integration/bpjs-vclaim/sep')
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('Error loading SEP detail:', error)
|
||||
toast({
|
||||
title: 'Gagal',
|
||||
description: error?.message || 'Gagal memuat data SEP',
|
||||
variant: 'destructive',
|
||||
})
|
||||
await navigateTo('/integration/bpjs-vclaim/sep')
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
isLoading,
|
||||
noSep,
|
||||
sepData,
|
||||
valueObjects,
|
||||
getSepDetail,
|
||||
}
|
||||
}
|
||||
@@ -54,6 +54,7 @@ export function useIntegrationSepEntry() {
|
||||
const userStore = useUserStore()
|
||||
const route = useRoute()
|
||||
|
||||
const recSepId = ref<number | null>(null)
|
||||
const openPatient = ref(false)
|
||||
const openLetter = ref(false)
|
||||
const openHistory = ref(false)
|
||||
@@ -87,6 +88,7 @@ export function useIntegrationSepEntry() {
|
||||
const specialistsTree = ref<TreeItem[]>([])
|
||||
const resourceType = ref('')
|
||||
const resourcePath = ref('')
|
||||
const encounterId = ref<number | string | null>(null)
|
||||
|
||||
/**
|
||||
* Map letter data to form fields for save-sep
|
||||
@@ -176,17 +178,17 @@ export function useIntegrationSepEntry() {
|
||||
return mappedValues
|
||||
}
|
||||
|
||||
async function getMonitoringHistoryMappers() {
|
||||
async function getMonitoringHistoryMappers(number: string | null = null) {
|
||||
histories.value = []
|
||||
const dateFirst = new Date()
|
||||
const dateLast = new Date()
|
||||
dateLast.setMonth(dateFirst.getMonth() - 3)
|
||||
dateLast.setMonth(dateFirst.getMonth() - 2) // max 90 days
|
||||
const cardNumber =
|
||||
selectedPatientObject.value?.person?.residentIdentityNumber || selectedPatientObject.value?.number || ''
|
||||
selectedPatientObject.value?.person?.residentIdentityNumber || selectedPatientObject.value?.number || number || ''
|
||||
const result = await getMonitoringHistoryList({
|
||||
cardNumber: cardNumber,
|
||||
startDate: dateFirst.toISOString().substring(0, 10),
|
||||
endDate: dateLast.toISOString().substring(0, 10),
|
||||
startDate: dateLast.toISOString().substring(0, 10),
|
||||
endDate: dateFirst.toISOString().substring(0, 10),
|
||||
})
|
||||
if (result && result.success && result.body) {
|
||||
const historiesRaw = result.body?.response?.histori || []
|
||||
@@ -441,6 +443,10 @@ export function useIntegrationSepEntry() {
|
||||
if (menu === 'back') {
|
||||
navigateTo('/integration/bpjs-vclaim/sep')
|
||||
}
|
||||
if (menu === 'save-sep-number') {
|
||||
const sourcePath = route.query['source-path'] || ('' as any)
|
||||
navigateTo({ path: sourcePath, query: { 'sep-number': value.sepNumber || '' } })
|
||||
}
|
||||
if (menu === 'save-sep') {
|
||||
isSaveLoading.value = true
|
||||
|
||||
@@ -481,22 +487,33 @@ export function useIntegrationSepEntry() {
|
||||
}
|
||||
|
||||
mappedValues.userName = userStore.user?.user_name || ''
|
||||
const payload = { ...makeSepData(mappedValues), encounterId: encounterId.value || null }
|
||||
|
||||
createSep(makeSepData(mappedValues))
|
||||
createSep(payload)
|
||||
.then((res) => {
|
||||
const body = res?.body
|
||||
const code = body?.metaData?.code
|
||||
const message = body?.metaData?.message
|
||||
if (code && code !== '200') {
|
||||
toast({ title: 'Gagal', description: message || 'Gagal membuat SEP', variant: 'destructive' })
|
||||
const success = res?.success
|
||||
if (success) {
|
||||
const body = res?.body
|
||||
const code = body?.metaData?.code
|
||||
const message = body?.metaData?.message
|
||||
if (code && code !== '200') {
|
||||
toast({ title: 'Gagal', description: message || 'Gagal membuat SEP', variant: 'destructive' })
|
||||
return
|
||||
}
|
||||
toast({ title: 'Berhasil', description: 'SEP berhasil dibuat', variant: 'default' })
|
||||
if (!!resourcePath.value) {
|
||||
navigateTo({ path: resourcePath.value, query: { 'sep-number': body?.response?.sep?.noSep || '-' } })
|
||||
return
|
||||
}
|
||||
navigateTo('/integration/bpjs-vclaim/sep')
|
||||
return
|
||||
}
|
||||
toast({ title: 'Berhasil', description: 'SEP berhasil dibuat', variant: 'default' })
|
||||
if (!!resourcePath.value) {
|
||||
navigateTo({ path: resourcePath.value, query: { 'sep-number': body?.response?.sep?.noSep || '-' } })
|
||||
const error = res?.error
|
||||
if (error) {
|
||||
const errorMessage = error?.message ? `${error?.message}` : 'Sep gagal dibuat'
|
||||
toast({ title: 'Gagal', description: errorMessage, variant: 'destructive' })
|
||||
return
|
||||
}
|
||||
navigateTo('/integration/bpjs-vclaim/sep')
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('Failed to save SEP:', err)
|
||||
@@ -609,6 +626,7 @@ export function useIntegrationSepEntry() {
|
||||
const queries = route.query as any
|
||||
isServiceHidden.value = queries['is-service'] === 'true'
|
||||
selectedObjects.value = {}
|
||||
if (queries['encounter-id']) encounterId.value = queries['encounter-id']
|
||||
if (queries['resource']) resourceType.value = queries['resource']
|
||||
if (queries['source-path']) resourcePath.value = queries['source-path']
|
||||
if (queries['doctor-code']) selectedObjects.value['doctorCode'] = queries['doctor-code']
|
||||
@@ -624,18 +642,18 @@ export function useIntegrationSepEntry() {
|
||||
await getPatientInternalMappers(queries['patient-id'])
|
||||
}
|
||||
if (queries['card-number']) {
|
||||
const resultMember = await getMemberList({
|
||||
await getMemberList({
|
||||
mode: 'by-card',
|
||||
number: queries['card-number'],
|
||||
date: new Date().toISOString().substring(0, 10),
|
||||
})
|
||||
console.log(resultMember)
|
||||
}
|
||||
delete selectedObjects.value['is-service']
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
recSepId,
|
||||
openPatient,
|
||||
openLetter,
|
||||
openHistory,
|
||||
@@ -669,6 +687,7 @@ export function useIntegrationSepEntry() {
|
||||
specialistsTree,
|
||||
resourceType,
|
||||
resourcePath,
|
||||
encounterId,
|
||||
patients,
|
||||
selectedPatient,
|
||||
paginationMeta,
|
||||
@@ -687,5 +706,3 @@ export function useIntegrationSepEntry() {
|
||||
handleInit,
|
||||
}
|
||||
}
|
||||
|
||||
export default useIntegrationSepEntry
|
||||
@@ -14,7 +14,7 @@ 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'
|
||||
import { remove as removeSepData, removeOld as removeSepDataOld, makeSepDataForRemove } from '~/services/vclaim-sep.service'
|
||||
|
||||
const headerKeys = [
|
||||
'letterDate',
|
||||
@@ -224,10 +224,11 @@ export function useIntegrationSepList() {
|
||||
}
|
||||
|
||||
const handleRemove = async () => {
|
||||
const isNew = true;
|
||||
try {
|
||||
const result = await removeSepData(
|
||||
const result = !isNew ? await removeSepDataOld(
|
||||
makeSepDataForRemove({ ...sepData.value, userName: userStore.user?.user_name }),
|
||||
)
|
||||
) : await removeSepData(sepData.value.sepNumber || '')
|
||||
const backendMessage = result?.body?.message || result?.message || null
|
||||
const backendStatus = result?.body?.status || result?.status || null
|
||||
|
||||
@@ -280,5 +281,3 @@ export function useIntegrationSepList() {
|
||||
handleRemove,
|
||||
}
|
||||
}
|
||||
|
||||
export default useIntegrationSepList
|
||||
Reference in New Issue
Block a user