Files
clinicpro/assets/admin/hooks/useIssueInvoice.ts
T
hamedandClaude Opus 4.8 76bfa5d36f fix: issue invoice on demand so view-invoice buttons actually work
The admin SPA never called POST /billing/invoices, so every session had
invoice_uuid = null and the view-invoice buttons on the patient services
tab (and MyPatients visit modal) were permanently disabled. Add a shared
useIssueInvoice hook (idempotent create + finalize when draft) and wire
it into:
- DetailsStep: the wizard's final step now really issues the invoice
- SessionServiceCard / PatientDetailPage: clicking view-invoice on a
  session without an invoice issues it first, then opens the summary
- MyPatientsPage visit modal: same, replacing the dead disabled button

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 15:39:02 +03:30

30 lines
1.2 KiB
TypeScript

import { useMutation, useQueryClient } from '@tanstack/react-query';
import { api } from '../lib/api';
interface InvoicePayload { uuid: string; status: string }
/**
* صدور فاکتور یک مراجعه: ساخت idempotent (`POST /billing/invoices`) و سپس
* نهایی‌سازی draft. خروجی mutation، uuid فاکتور است تا caller مودال «خلاصه
* فاکتور» را باز کند. با recordUuid، لیست sessions همان بیمار invalidate
* می‌شود تا invoice_uuid کارت‌ها به‌روز شود.
*/
export function useIssueInvoice(recordUuid?: string) {
const qc = useQueryClient();
return useMutation({
mutationFn: async (sessionUuid: string): Promise<string> => {
const res = await api.post<any>('/api/v1/billing/invoices', { session_uuid: sessionUuid });
const invoice = ((res as any)?.data?.data ?? (res as any)?.data) as InvoicePayload;
if (invoice.status === 'draft') {
await api.post(`/api/v1/billing/invoices/${invoice.uuid}/finalize`, {});
}
return invoice.uuid;
},
onSuccess: () => {
if (recordUuid) qc.invalidateQueries({ queryKey: ['patient-sessions', recordUuid] });
qc.invalidateQueries({ queryKey: ['invoice'] });
},
});
}