import { toast } from 'sonner'; import { formatRial, formatDateTime } from '../../lib/utils'; import type { SessionCardData } from '../SessionServiceCard'; import { METHOD_LABELS } from './PaymentStep'; import { useIssueInvoice } from '../../hooks/useIssueInvoice'; const primaryBtn: React.CSSProperties = { background: '#5559CE', color: '#fff', border: 'none', borderRadius: 4, height: 46, fontSize: 14, fontWeight: 500, cursor: 'pointer' }; const ghostBtn: React.CSSProperties = { background: 'transparent', color: '#5559CE', border: '1px solid #5559CE', borderRadius: 4, height: 46, fontSize: 14, fontWeight: 500, cursor: 'pointer' }; interface Props { session: SessionCardData; /** برای invalidate شدن لیست sessions بعد از صدور فاکتور. */ recordUuid?: string; onBack: () => void; onFinish: () => void; } /** * گام «جزییات» — پورت tauri Step3Final با دیتای واقعی: * خلاصهی سرویس/هزینه/تخفیف + لیست پرداختشدهها + مانده. مشترک بین * NewSessionPage (ویزارد سهگامه) و SessionPaymentPage (دوگامه). * «صدور فاکتور» فاکتور را واقعاً صادر میکند (create + finalize) و بعد onFinish. */ export default function DetailsStep({ session, recordUuid, onBack, onFinish }: Props) { const issueMut = useIssueInvoice(recordUuid); const issue = () => { if (session.invoice_uuid) { onFinish(); return; } issueMut.mutate(session.uuid, { onSuccess: () => onFinish(), onError: () => toast.error('صدور فاکتور ناموفق بود'), }); }; const finalPrice = session.final_price_rials ?? 0; const discountRials = session.discount_rials ?? 0; const debt = session.patient_debt_rials ?? 0; const payments = session.payments ?? []; const visitPrice = session.visit_price_rials ?? 0; const serviceNames = (session.services ?? []).map((s) => s.service_name || s.name).filter(Boolean) as string[]; if (visitPrice > 0) serviceNames.unshift('ویزیت'); // زمان مراجعه: زمان واقعی نوبت؛ در نبود آن، زمان ثبت پرونده. const visitAt = session.session_at ?? session.created_at ?? null; // آیتمهای هزینهی تفکیکشده: ویزیت + هر سرویس + کالای مصرفی. // کالای مصرفی هم باید بیاید چون سرور آن را در سهم بیمار میآورد // (PatientService::…$consumablesTotal)؛ نبودش ریز هزینهها را با جمع ناسازگار میکرد. const costItems: Array<{ label: string; rials: number }> = []; if (visitPrice > 0) costItems.push({ label: 'ویزیت', rials: visitPrice }); (session.services ?? []).forEach((s) => { costItems.push({ label: (s.service_name || s.name) ?? 'سرویس', rials: s.line_total_rials ?? (s.price_rials ?? 0) * (s.quantity ?? 1), }); }); (session.consumables ?? []).forEach((c) => { costItems.push({ label: c.item_name ?? 'کالای مصرفی', rials: c.line_total_rials ?? 0, }); }); // خطوط بالا ناخالصاند (پیش از بیمه) ولی finalPrice سهمِ بیمار پس از بیمه است. // پس وقتی بیمه هست، جمعِ خطوط را ناخالص نشان بده و سهم بیمه را جدا کم کن. const grossTotal = session.gross_total_rials ?? finalPrice; const baseInsurance = session.base_insurance_rials ?? 0; const suppInsurance = session.supplementary_insurance_rials ?? 0; const hasInsurance = baseInsurance > 0 || suppInsurance > 0; return ( <> {/* گام جزییات — پورت tauri Step3Final با دیتای واقعی */}