diff --git a/app/components/app/encounter/entry-form.vue b/app/components/app/encounter/entry-form.vue
index 29a75302..c4ada1db 100644
--- a/app/components/app/encounter/entry-form.vue
+++ b/app/components/app/encounter/entry-form.vue
@@ -24,6 +24,8 @@ import { useForm } from 'vee-validate'
const props = defineProps<{
isLoading?: boolean
isReadonly?: boolean
+ isSepValid?: boolean
+ isCheckingSep?: boolean
doctor?: any[]
subSpecialist?: any[]
specialists?: TreeItem[]
@@ -61,6 +63,10 @@ const patientId = ref('')
const isLoading = props.isLoading !== undefined ? props.isLoading : false
const isReadonly = props.isReadonly !== undefined ? props.isReadonly : false
+// SEP validation state from props
+const isSepValid = computed(() => props.isSepValid || false)
+const isCheckingSep = computed(() => props.isCheckingSep || false)
+
const doctorOpts = computed(() => {
// Add default option
const defaultOption = [{ label: 'Pilih', value: '' }]
@@ -86,6 +92,11 @@ watch(subSpecialistId, async (newValue) => {
}
})
+// Watch SEP number changes to notify parent
+watch(sepNumber, (newValue) => {
+ emit('event', 'sep-number-changed', newValue)
+})
+
// Sync props to form fields
watch(
() => props.objects,
@@ -403,13 +414,33 @@ defineExpose({
:disabled="isLoading || isReadonly"
/>
+
diff --git a/app/components/content/encounter/entry.vue b/app/components/content/encounter/entry.vue
index 580031d9..8b88c388 100644
--- a/app/components/content/encounter/entry.vue
+++ b/app/components/content/encounter/entry.vue
@@ -19,6 +19,10 @@ import {
} from '~/services/specialist.service'
import { getValueLabelList as getDoctorValueLabelList } from '~/services/doctor.service'
import { create as createEncounter, getDetail as getEncounterDetail, update as updateEncounter } from '~/services/encounter.service'
+import { getList as getSepList } from '~/services/vclaim-sep.service'
+
+// Helpers
+import { refDebounced } from '@vueuse/core'
// Handlers
import {
@@ -60,6 +64,12 @@ const formRef = ref | null>(null)
const encounterData = ref(null)
const formObjects = ref({})
+// SEP validation state
+const isSepValid = ref(false)
+const isCheckingSep = ref(false)
+const sepNumber = ref('')
+const debouncedSepNumber = refDebounced(sepNumber, 500)
+
// Computed for edit mode
const isEditMode = computed(() => props.id > 0)
@@ -236,6 +246,10 @@ async function handleEvent(menu: string, value?: any) {
} else if (menu === 'add') {
navigateTo('/client/patient/add')
} else if (menu === 'add-sep') {
+ // If SEP is already valid, don't navigate
+ if (isSepValid.value) {
+ return
+ }
recSelectId.value = null
toNavigateSep({
isService: 'false',
@@ -243,6 +257,11 @@ async function handleEvent(menu: string, value?: any) {
resource: `${props.classCode}-${props.subClassCode}`,
...value,
})
+ } else if (menu === 'sep-number-changed') {
+ // Update sepNumber when it changes in form (only if different to prevent loop)
+ if (sepNumber.value !== value) {
+ sepNumber.value = value || ''
+ }
} else if (menu === 'save') {
await handleSaveEncounter(value)
} else if (menu === 'cancel') {
@@ -250,6 +269,63 @@ async function handleEvent(menu: string, value?: any) {
}
}
+/**
+ * Validate SEP number
+ */
+async function validateSepNumber(sepNumberValue: string) {
+ // Reset validation if SEP number is empty
+ if (!sepNumberValue || sepNumberValue.trim() === '') {
+ isSepValid.value = false
+ isCheckingSep.value = false
+ return
+ }
+
+ // Only check if payment type is JKN
+ // We need to check from formObjects
+ const paymentType = formObjects.value?.paymentType
+ if (paymentType !== 'jkn') {
+ isSepValid.value = false
+ return
+ }
+
+ try {
+ isCheckingSep.value = true
+ const result = await getSepList({ number: sepNumberValue.trim() })
+
+ // Check if SEP is found
+ // If response is not null, SEP is found
+ // If response is null with metaData code "201", SEP is not found
+ if (result.success && result.body?.response !== null) {
+ isSepValid.value = true
+ } else {
+ // SEP not found (response null with metaData code "201")
+ isSepValid.value = false
+ }
+ } catch (error) {
+ console.error('Error checking SEP:', error)
+ isSepValid.value = false
+ } finally {
+ isCheckingSep.value = false
+ }
+}
+
+// Watch debounced SEP number to validate
+watch(debouncedSepNumber, async (newValue) => {
+ await validateSepNumber(newValue)
+})
+
+// Watch payment type to reset SEP validation
+watch(
+ () => formObjects.value?.paymentType,
+ (newValue) => {
+ isSepValid.value = false
+ // If payment type is not JKN, clear SEP number
+ if (newValue !== 'jkn') {
+ sepNumber.value = ''
+ }
+ },
+)
+
async function handleFetchSpecialists() {
try {
const specialistsResult = await getSpecialistList({ 'page-size': 100, includes: 'subspecialists' })
@@ -583,6 +659,11 @@ async function mapEncounterToForm(encounter: any) {
// Set form objects for the form component
formObjects.value = formData
+ // Update sepNumber for validation
+ if (formData.sepNumber) {
+ sepNumber.value = formData.sepNumber
+ }
+
// Fetch doctors based on specialist/subspecialist selection
if (formData.subSpecialistId) {
await handleFetchDoctors(formData.subSpecialistId)
@@ -613,6 +694,9 @@ onMounted(async () => {
{
:doctor="doctorsList"
:patient="selectedPatientObject"
:objects="formObjects"
- :is-loading="isLoadingDetail"
@event="handleEvent"
@fetch="handleFetch"
/>
diff --git a/app/services/vclaim-sep.service.ts b/app/services/vclaim-sep.service.ts
index 5a19d7c9..fdccc9c4 100644
--- a/app/services/vclaim-sep.service.ts
+++ b/app/services/vclaim-sep.service.ts
@@ -11,6 +11,15 @@ export function create(data: any) {
return base.create(path, data, name)
}
+export function getList(params: any = null) {
+ let url = path
+ if (params?.number) {
+ url += `/${params.number}`
+ delete params.number
+ }
+ return base.getList(url, params, name)
+}
+
export function makeSepData(
data: IntegrationBpjsFormData & {
referralFrom?: string
@@ -20,7 +29,7 @@ export function makeSepData(
},
) {
const content = {
- noKartu: data.bpjsNumber || '',
+ noKartu: data.cardNumber || '',
tglSep: data.sepDate,
ppkPelayanan: data.fromClinic || '',
jnsPelayanan: data.admissionType ? String(data.admissionType) : '1',