feat(patients): visit insurance options from tenant contracts + auto coverage%
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -23,8 +23,7 @@ const schema = z.object({
|
||||
});
|
||||
type FormData = z.infer<typeof schema>;
|
||||
|
||||
interface PricingInsurance { insurance_id: number; insurance_name: string; type: string; patient_share_rials: number | null }
|
||||
interface InsurancePricing { free_visit_price_rials: number; insurances: PricingInsurance[] }
|
||||
interface Contract { insurance_id: number; insurance_name: string | null; insurance_kind: string | null; coverage_percent: number }
|
||||
|
||||
const PAYMENT_LABELS: Record<string, string> = {
|
||||
cash: 'نقدی', card: 'کارت', insurance: 'بیمه', online: 'آنلاین', pending: 'در انتظار',
|
||||
@@ -71,36 +70,27 @@ export default function NewSessionPage() {
|
||||
queryFn: () => api.get(`/api/v1/service-items/${sectionUuid}`),
|
||||
enabled: !!sectionUuid,
|
||||
});
|
||||
const { data: pricingData } = useQuery<ApiResponse<InsurancePricing>>({
|
||||
queryKey: ['insurance-pricing'], queryFn: () => api.get('/api/v1/insurance-pricing'),
|
||||
const { data: contractsData } = useQuery<{ data: { data: Contract[] } }>({
|
||||
queryKey: ['tenant-insurances'], queryFn: () => api.get('/api/v1/billing/tenant-insurances'),
|
||||
});
|
||||
|
||||
const pricing = (pricingData?.data as InsurancePricing | undefined) ?? undefined;
|
||||
const freeVisit = pricing?.free_visit_price_rials ?? 0;
|
||||
const baseOpts = (pricing?.insurances ?? []).filter(i => i.type === 'basic').map(i => ({ value: String(i.insurance_id), label: i.insurance_name }));
|
||||
const suppOpts = (pricing?.insurances ?? []).filter(i => i.type === 'supplementary').map(i => ({ value: String(i.insurance_id), label: i.insurance_name }));
|
||||
const contracts = (contractsData as any)?.data?.data as Contract[] | undefined ?? [];
|
||||
const baseOpts = contracts.filter(c => c.insurance_kind === 'basic').map(c => ({ value: String(c.insurance_id), label: c.insurance_name ?? `#${c.insurance_id}` }));
|
||||
const suppOpts = contracts.filter(c => c.insurance_kind === 'supplementary').map(c => ({ value: String(c.insurance_id), label: c.insurance_name ?? `#${c.insurance_id}` }));
|
||||
|
||||
const sectionOptions = (sectionsData?.data ?? []).map(s => ({ value: s.uuid, label: s.name }));
|
||||
const itemOptions = (itemsData?.data ?? []).filter(i => i.active).map(i => ({ value: i.uuid, label: `${i.name} — ${formatRial(i.price_rials)}` }));
|
||||
|
||||
const shareToPercent = (id: string): number => {
|
||||
if (!id || freeVisit <= 0) return 0;
|
||||
const ins = pricing?.insurances.find(i => String(i.insurance_id) === id);
|
||||
if (!ins || ins.patient_share_rials == null) return 0;
|
||||
return Math.round((Math.max(0, freeVisit - ins.patient_share_rials) / freeVisit) * 1000) / 10;
|
||||
};
|
||||
const coverageOf = (id: string): number => contracts.find(c => String(c.insurance_id) === id)?.coverage_percent ?? 0;
|
||||
const applyBase = (id: string) => {
|
||||
setBaseId(id);
|
||||
form.setValue('insurance_base_id', id ? Number(id) : undefined);
|
||||
if (id && freeVisit > 0) {
|
||||
form.setValue('visit_price_rials', freeVisit);
|
||||
form.setValue('base_insurance_discount_percent', shareToPercent(id));
|
||||
}
|
||||
form.setValue('base_insurance_discount_percent', id ? coverageOf(id) : 0);
|
||||
};
|
||||
const applySupp = (id: string) => {
|
||||
setSuppId(id);
|
||||
form.setValue('insurance_supplementary_id', id ? Number(id) : undefined);
|
||||
if (id) form.setValue('supplementary_discount_percent', shareToPercent(id));
|
||||
form.setValue('supplementary_discount_percent', id ? coverageOf(id) : 0);
|
||||
};
|
||||
|
||||
const addService = () => {
|
||||
|
||||
Reference in New Issue
Block a user