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:
hamed
2026-06-23 22:17:37 +03:30
co-authored by Claude Opus 4.8
parent 0e6111f1be
commit 43e8822db5
+9 -19
View File
@@ -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 = () => {