feat(sep): add error message
This commit is contained in:
@@ -19,11 +19,11 @@ import type { PatientEntity } from '~/models/patient'
|
||||
// Helpers
|
||||
import { toTypedSchema } from '@vee-validate/zod'
|
||||
import { useForm } from 'vee-validate'
|
||||
import { is } from "date-fns/locale"
|
||||
|
||||
const props = defineProps<{
|
||||
isLoading?: boolean
|
||||
isReadonly?: boolean
|
||||
isService?: boolean
|
||||
mode?: string
|
||||
doctors: any[]
|
||||
diagnoses: any[]
|
||||
@@ -43,6 +43,7 @@ const props = defineProps<{
|
||||
cities: any[]
|
||||
districts: any[]
|
||||
patient?: PatientEntity | null | undefined
|
||||
objects?: any
|
||||
values?: any
|
||||
}>()
|
||||
|
||||
@@ -51,12 +52,8 @@ const emit = defineEmits<{
|
||||
(e: 'fetch', value?: any): void
|
||||
}>()
|
||||
|
||||
const mode = props.mode !== undefined ? props.mode : 'add'
|
||||
const isLoading = props.isLoading !== undefined ? props.isLoading : false
|
||||
const isReadonly = props.isReadonly !== undefined ? props.isReadonly : false
|
||||
|
||||
// Validation schema (moved to shared file)
|
||||
const { handleSubmit, errors, defineField, meta } = useForm<IntegrationBpjsFormData>({
|
||||
const { handleSubmit, errors, defineField } = useForm<IntegrationBpjsFormData>({
|
||||
validationSchema: toTypedSchema(IntegrationBpjsSchema),
|
||||
})
|
||||
|
||||
@@ -103,17 +100,15 @@ const titleLetterDate = computed(() =>
|
||||
const isAccidentally = computed(() => accident.value === '1' || accident.value === '2')
|
||||
const isProvinceSelected = computed(() => accidentProvince.value !== '')
|
||||
const isCitySelected = computed(() => accidentCity.value !== '')
|
||||
const mode = props.mode !== undefined ? props.mode : 'add'
|
||||
const isLoading = props.isLoading !== undefined ? props.isLoading : false
|
||||
const isReadonly = props.isReadonly !== undefined ? props.isReadonly : false
|
||||
const isService = ref(props.isService || false)
|
||||
|
||||
if (mode === 'add') {
|
||||
// sepDate.value = new Date().toISOString()
|
||||
}
|
||||
|
||||
// Submit handler
|
||||
const onSubmit = handleSubmit((values) => {
|
||||
console.log('✅ Validated form values:', JSON.stringify(values, null, 2))
|
||||
emit('event', 'save-sep', values)
|
||||
})
|
||||
|
||||
watch(props, (value) => {
|
||||
const patient = value.patient || ({} as PatientEntity)
|
||||
if (Object.keys(patient).length > 0) {
|
||||
@@ -124,6 +119,18 @@ watch(props, (value) => {
|
||||
phoneNumber.value = '-'
|
||||
}
|
||||
})
|
||||
|
||||
// Submit handler
|
||||
const onSubmit = handleSubmit((values) => {
|
||||
console.log('✅ Validated form values:', JSON.stringify(values, null, 2))
|
||||
emit('event', 'save-sep', values)
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
if (!isService.value) {
|
||||
serviceType.value = '2'
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -155,7 +162,7 @@ watch(props, (value) => {
|
||||
</Field>
|
||||
</Cell>
|
||||
|
||||
<Cell>
|
||||
<Cell v-if="isService">
|
||||
<Label height="compact">Pelayanan</Label>
|
||||
<Field :errMessage="errors.serviceType">
|
||||
<Select
|
||||
@@ -374,7 +381,7 @@ watch(props, (value) => {
|
||||
</Field>
|
||||
</Cell>
|
||||
|
||||
<Cell>
|
||||
<Cell v-if="serviceType === '1'">
|
||||
<Label height="compact">
|
||||
Faskes Asal
|
||||
<span class="text-red-500">*</span>
|
||||
@@ -484,8 +491,11 @@ watch(props, (value) => {
|
||||
:cellFlex="false"
|
||||
>
|
||||
<Cell>
|
||||
<Label height="dynamic">Kelas Rawat</Label>
|
||||
<Field>
|
||||
<Label height="dynamic">
|
||||
Kelas Rawat
|
||||
<span class="text-red-500">*</span>
|
||||
</Label>
|
||||
<Field :errMessage="errors.classLevel">
|
||||
<Select
|
||||
id="classLevel"
|
||||
v-model="classLevel"
|
||||
@@ -498,8 +508,11 @@ watch(props, (value) => {
|
||||
</Cell>
|
||||
|
||||
<Cell>
|
||||
<Label height="dynamic">Kelas Rawat Naik</Label>
|
||||
<Field>
|
||||
<Label height="dynamic">
|
||||
Kelas Rawat Naik
|
||||
<span class="text-red-500">*</span>
|
||||
</Label>
|
||||
<Field :errMessage="errors.classLevelUpgrade">
|
||||
<Select
|
||||
id="classLevelUpgrade"
|
||||
v-model="classLevelUpgrade"
|
||||
@@ -512,8 +525,11 @@ watch(props, (value) => {
|
||||
</Cell>
|
||||
|
||||
<Cell>
|
||||
<Label height="dynamic">Pembiayaan</Label>
|
||||
<Field>
|
||||
<Label height="dynamic">
|
||||
Pembiayaan
|
||||
<span class="text-red-500">*</span>
|
||||
</Label>
|
||||
<Field :errMessage="errors.classPaySource">
|
||||
<Select
|
||||
id="classPaySource"
|
||||
v-model="classPaySource"
|
||||
@@ -534,8 +550,11 @@ watch(props, (value) => {
|
||||
:cellFlex="false"
|
||||
>
|
||||
<Cell>
|
||||
<Label height="dynamic">Penanggung Jawab</Label>
|
||||
<Field>
|
||||
<Label height="dynamic">
|
||||
Penanggung Jawab
|
||||
<span class="text-red-500">*</span>
|
||||
</Label>
|
||||
<Field :errMessage="errors.responsiblePerson">
|
||||
<Input
|
||||
id="responsiblePerson"
|
||||
v-model="responsiblePerson"
|
||||
@@ -547,7 +566,6 @@ watch(props, (value) => {
|
||||
</Cell>
|
||||
</Block>
|
||||
|
||||
|
||||
<Block
|
||||
labelSize="thin"
|
||||
class="!pt-0"
|
||||
@@ -893,9 +911,10 @@ watch(props, (value) => {
|
||||
Preview
|
||||
</Button>
|
||||
<Button
|
||||
type="submit"
|
||||
type="button"
|
||||
class="h-[40px] min-w-[120px] text-white"
|
||||
:disabled="isLoading || !meta.valid"
|
||||
:disabled="isLoading"
|
||||
@click="onSubmit"
|
||||
>
|
||||
<Icon
|
||||
name="i-lucide-save"
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useRoute } from 'vue-router'
|
||||
|
||||
// Components
|
||||
import AppViewHistory from '~/components/app/sep/view-history.vue'
|
||||
import { toast } from '~/components/pub/ui/toast'
|
||||
|
||||
// Types
|
||||
import type { PaginationMeta } from '~/components/pub/my-ui/pagination/pagination.type'
|
||||
@@ -67,6 +68,8 @@ const classLevelsList = ref<Array<{ value: string; label: string }>>([])
|
||||
const classLevelUpgradesList = ref<Array<{ value: string; label: string }>>([])
|
||||
const classPaySourcesList = ref<Array<{ value: string; label: string }>>([])
|
||||
const isPatientsLoading = ref(false)
|
||||
const isServiceHidden = ref(false)
|
||||
const isSaveLoading = ref(false)
|
||||
const paginationMeta = ref<PaginationMeta>({
|
||||
recordCount: 0,
|
||||
page: 1,
|
||||
@@ -77,7 +80,6 @@ const paginationMeta = ref<PaginationMeta>({
|
||||
})
|
||||
|
||||
function mapPatientToRow(patient: PatientEntity) {
|
||||
// Defensive mapping: try common field names that might be returned by the API
|
||||
const identity = patient?.person?.residentIdentityNumber || '-'
|
||||
const number = patient?.number || '-'
|
||||
const bpjs = '-'
|
||||
@@ -175,7 +177,6 @@ async function getMonitoringVisitMappers() {
|
||||
if (result && result.success && result.body) {
|
||||
const visitsRaw = result.body?.response?.sep || []
|
||||
|
||||
// "diagnosa": "K65.0",
|
||||
// "jnsPelayanan": "R.Inap",
|
||||
// "kelasRawat": "2",
|
||||
// "nama": "HANIF ABDURRAHMAN",
|
||||
@@ -269,10 +270,24 @@ async function handleEvent(menu: string, value: any) {
|
||||
navigateTo('/integration/bpjs/sep')
|
||||
}
|
||||
if (menu === 'save-sep') {
|
||||
createSep(makeSepData(value)).then((value) => {
|
||||
console.log('value:', value)
|
||||
// navigateTo('/integration/bpjs/sep')
|
||||
})
|
||||
isSaveLoading.value = true
|
||||
createSep(makeSepData(value))
|
||||
.then((res) => {
|
||||
const code = res?.metaData?.code
|
||||
const message = res?.metaData?.message
|
||||
if (code && code !== '200') {
|
||||
toast({ title: 'Gagal', description: message || 'Gagal membuat SEP', variant: 'destructive' })
|
||||
} else {
|
||||
toast({ title: 'Berhasil', description: 'SEP berhasil dibuat', variant: 'default' })
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('Failed to save SEP:', err)
|
||||
toast({ title: 'Gagal', description: err?.message || 'Gagal membuat SEP', variant: 'destructive' })
|
||||
})
|
||||
.finally(() => {
|
||||
isSaveLoading.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,7 +337,7 @@ async function handleInit() {
|
||||
label: serviceTypes[item],
|
||||
})) as any
|
||||
registerMethodsList.value = Object.keys(registerMethods)
|
||||
.filter((item) => !['2', '4'].includes(item))
|
||||
.filter((item) => !['4'].includes(item))
|
||||
.map((item) => ({
|
||||
value: item.toString(),
|
||||
label: registerMethods[item],
|
||||
@@ -364,9 +379,11 @@ async function handleInit() {
|
||||
onMounted(async () => {
|
||||
await handleInit()
|
||||
if (route.query) {
|
||||
selectedObjects.value = { ...route.query }
|
||||
const queries = route.query as any
|
||||
selectedObjects.value = { ...queries }
|
||||
isServiceHidden.value = queries['is-service'] === 'true'
|
||||
delete selectedObjects.value['is-service']
|
||||
}
|
||||
console.log('selectedObjects:', selectedObjects.value)
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -379,6 +396,7 @@ onMounted(async () => {
|
||||
<span class="font-semibold">Tambah</span>
|
||||
SEP
|
||||
</div>
|
||||
Hallo {{ isServiceHidden }}
|
||||
<AppSepEntryForm
|
||||
:doctors="doctors"
|
||||
:diagnoses="diagnoses"
|
||||
@@ -398,6 +416,8 @@ onMounted(async () => {
|
||||
:class-level-upgrades="classLevelUpgradesList"
|
||||
:class-pay-sources="classPaySourcesList"
|
||||
:patient="selectedPatientObject"
|
||||
:is-save-loading="isSaveLoading"
|
||||
:is-service="isServiceHidden"
|
||||
@fetch="handleFetch"
|
||||
@event="handleEvent"
|
||||
/>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import * as base from './_crud-base'
|
||||
|
||||
// Types
|
||||
import type { IntegrationBpjsFormData } from "~/schemas/integration-bpjs.schema"
|
||||
import type { IntegrationBpjsFormData } from '~/schemas/integration-bpjs.schema'
|
||||
|
||||
const path = '/api/vclaim/sep'
|
||||
const name = 'sep'
|
||||
@@ -11,31 +11,20 @@ export function create(data: any) {
|
||||
return base.create(path, data, name)
|
||||
}
|
||||
|
||||
export function makeSepData(data: IntegrationBpjsFormData) {
|
||||
// "nationalId": "5617213001231231",
|
||||
// "referralLetterNumber": "12233",
|
||||
// "referralLetterDate": "2025-10-21",
|
||||
// "attendingDoctor": "25107",
|
||||
|
||||
console.log('data:', data)
|
||||
export function makeSepData(
|
||||
data: IntegrationBpjsFormData & {
|
||||
referralFrom?: string
|
||||
referralTo?: string
|
||||
referralLetterDate?: string
|
||||
referralLetterNumber?: string
|
||||
},
|
||||
) {
|
||||
const content = {
|
||||
noKartu: data.bpjsNumber || '',
|
||||
tglSep: data.sepDate,
|
||||
ppkPelayanan: data.serviceType || '',
|
||||
jnsPelayanan: data.admissionType ? String(data.admissionType) : '1',
|
||||
klsRawat: {
|
||||
klsRawatHak: '2',
|
||||
klsRawatNaik: '',
|
||||
pembiayaan: '',
|
||||
penanggungJawab: '',
|
||||
},
|
||||
noMR: data.medicalRecordNumber || '',
|
||||
rujukan: {
|
||||
asalRujukan: '1',
|
||||
tglRujukan: '2025-08-20',
|
||||
noRujukan: 'RJKMR9835001',
|
||||
ppkRujukan: '0301R011',
|
||||
},
|
||||
catatan: data.note || '',
|
||||
diagAwal: data.initialDiagnosis || '',
|
||||
poli: {
|
||||
@@ -53,10 +42,22 @@ export function makeSepData(data: IntegrationBpjsFormData) {
|
||||
kdPenunjang: data.supportCode || '',
|
||||
assesmentPel: data.serviceAssessment || '',
|
||||
skdp: {
|
||||
noSurat: '', // 0208R0060825K000001
|
||||
kodeDPJP: '', // 6546
|
||||
noSurat: data.admissionType === '3' ? data.referralLetterNumber : '',
|
||||
kodeDPJP: data.admissionType === '3' ? data.attendingDoctor : '',
|
||||
},
|
||||
dpjpLayan: '000002',
|
||||
rujukan: {
|
||||
asalRujukan: data?.referralFrom || '',
|
||||
tglRujukan: data?.referralLetterDate || '',
|
||||
noRujukan: data?.referralLetterNumber || '',
|
||||
ppkRujukan: data?.referralTo || '',
|
||||
},
|
||||
klsRawat: {
|
||||
klsRawatHak: data.classLevel || '',
|
||||
klsRawatNaik: data.classLevelUpgrade || '',
|
||||
pembiayaan: data.classPaySource || '',
|
||||
penanggungJawab: data.responsiblePerson || '',
|
||||
},
|
||||
dpjpLayan: data.attendingDoctor || '',
|
||||
noTelp: data.phoneNumber || '',
|
||||
user: data.patientName || '',
|
||||
jaminan: {
|
||||
|
||||
Reference in New Issue
Block a user