Files
simrsx-fe/app/schemas/integration-encounter.schema.ts

157 lines
5.0 KiB
TypeScript

import { isValid } from "date-fns"
import { z } from 'zod'
import { PatientSchema } from "./patient.schema"
import { PersonAddressSchema } from "./person-address.schema"
import { PersonContactBaseSchema } from "./person-contact.schema"
import { PersonAddressRelativeSchema } from "./person-address-relative.schema"
const ERROR_MESSAGES = {
required: {
doctor_code: 'Dokter wajib diisi',
registerDate: 'Tanggal Daftar wajib diisi',
paymentMethod_code: 'Jenis Pembayaran wajib diisi',
unit_code: 'Spesialis wajib diisi',
// specialist_code: 'Spesialis wajib diisi',
// subSpecialist_code: 'Subspesialis wajib diisi',
patientCategory: 'Kelompok Peserta wajib diisi',
cardNumber: 'No. Kartu BPJS wajib diisi',
sepType: 'Jenis SEP wajib diisi',
sepNumber: 'No. SEP wajib diisi',
},
}
const ACCEPTED_UPLOAD_TYPES = ['image/jpeg', 'image/png', 'application/pdf']
const isValidationSep = false
// const encounterPatientShcema = z.object({
// })
const IntegrationEncounterSchema = z
.object({
// Patient data (readonly, populated from selected patient)
patientSource: z.string().optional(),
patientName: z.string().optional(),
residentIdentiyNumber: z.string().optional(),
medicalRecordNumber: z.string().optional(),
// Visit data
doctor_code: z
.string({ required_error: ERROR_MESSAGES.required.doctor_code })
.min(1, ERROR_MESSAGES.required.doctor_code),
unit_code: z
.string({ required_error: ERROR_MESSAGES.required.unit_code })
.min(1, ERROR_MESSAGES.required.unit_code)
.optional(),
registerDate: z
.string({ required_error: ERROR_MESSAGES.required.registerDate })
.min(1, ERROR_MESSAGES.required.registerDate),
paymentMethod_code: z
.string({ required_error: ERROR_MESSAGES.required.paymentMethod_code })
.min(1, ERROR_MESSAGES.required.paymentMethod_code),
// BPJS related fields
patientCategory: z
.string()
.min(1, ERROR_MESSAGES.required.patientCategory)
.optional(),
cardNumber: z
.string()
.min(1, ERROR_MESSAGES.required.cardNumber)
.optional(),
sepType: z
.string()
.min(1, ERROR_MESSAGES.required.sepType)
.optional(),
sepNumber: z
.string({ required_error: ERROR_MESSAGES.required.sepNumber })
.optional(),
// File uploads
sepFile: z
.any()
.optional()
.refine((f) => !f || f instanceof File, { message: 'Harus berupa file yang valid' })
.refine((f) => !f || ACCEPTED_UPLOAD_TYPES.includes(f.type), {
message: 'Format file harus JPG, PNG, atau PDF',
})
.refine((f) => !f || f.size <= 1 * 1024 * 1024, { message: 'Maksimal 1MB' }),
sippFile: z
.any()
.optional()
.refine((f) => !f || f instanceof File, { message: 'Harus berupa file yang valid' })
.refine((f) => !f || ACCEPTED_UPLOAD_TYPES.includes(f.type), {
message: 'Format file harus JPG, PNG, atau PDF',
})
.refine((f) => !f || f.size <= 1 * 1024 * 1024, { message: 'Maksimal 1MB' }),
})
.refine(
(data) => {
// If payment type is jkn, then patient category is required
if (data.paymentMethod_code === 'jkn') {
return data.patientCategory && data.patientCategory.trim() !== ''
}
return true
},
{
message: ERROR_MESSAGES.required.patientCategory,
path: ['patientCategory'],
},
)
.refine(
(data) => {
// If payment type is jkn, then card number is required
if (data.paymentMethod_code === 'jkn') {
return data.cardNumber && data.cardNumber.trim() !== ''
}
return true
},
{
message: ERROR_MESSAGES.required.cardNumber,
path: ['cardNumber'],
},
)
.refine(
(data) => {
// If payment type is jkn, then SEP type is required
if (data.paymentMethod_code === 'jkn') {
return data.sepType && data.sepType.trim() !== ''
}
return true
},
{
message: ERROR_MESSAGES.required.sepType,
path: ['sepType'],
},
)
.refine(
(data) => {
// If payment type is jkn and SEP type is selected, then SEP number is required
if (isValidationSep && data.paymentMethod_code === 'jkn' && data.sepType && data.sepType.trim() !== '') {
return data.sepNumber && data.sepNumber.trim() !== ''
}
return true
},
{
message: ERROR_MESSAGES.required.sepNumber,
path: ['sepNumber'],
},
)
const IntegrationEncounterWPSchema = z
.object({
encounter: IntegrationEncounterSchema,
patient: z.object({
person: PatientSchema,
personAddresses: z.array(PersonAddressSchema),
personContacts: z.array(PersonContactBaseSchema),
personRelatives: z.array(PersonAddressRelativeSchema),
}),
})
type IntegrationEncounterFormData = z.infer<typeof IntegrationEncounterSchema>
type IntegrationEncounterWPFormData = z.infer<typeof IntegrationEncounterWPSchema>
export { IntegrationEncounterSchema, IntegrationEncounterWPSchema }
export type { IntegrationEncounterFormData, IntegrationEncounterWPFormData }