import { useQuery } from '@tanstack/react-query'; import { api } from '../lib/api'; import type { ApiResponse, PaginatedResponse } from '../lib/api'; /** * وضعیت پرداخت صورتحساب — مشتق از مجموع پرداخت‌های مراجعه در برابر سهم بیمار، * نه ستون `invoices.status` (که فقط چرخه‌ی حیات را نگه می‌دارد). */ export type PaymentRowStatus = 'paid' | 'partial' | 'unsettled'; /** One recorded invoice on the flat payments list (node 1). */ export interface PaymentRow { invoice_uuid: string; patient_uuid: string; patient_name: string | null; national_code: string | null; issued_at: number; amount_rials: number; paid_rials: number; status: PaymentRowStatus; } export interface PaymentFilters { page: number; national_code?: string; status?: string; // paid | partial | unsettled from?: number; // unix seconds to?: number; // unix seconds } /** همان وضعیت مشتق‌شده، روی جدول جزئیات بیمار (node 2). */ export type InvoiceRowStatus = PaymentRowStatus; export interface PatientInvoiceRow { uuid: string; number: number; issued_at: number; total_rials: number; patient_rials: number; paid_rials: number; status: InvoiceRowStatus; service_title: string | null; items: Array<{ uuid: string; title: string; quantity: number; total_rials: number; patient_rials: number }>; payments: InvoicePaymentRow[]; } /** یک پرداخت ثبت‌شده روی مراجعه‌ی همان صورتحساب. */ export interface InvoicePaymentRow { method: string; amount_rials: number; paid_at: number; created_by_name: string | null; } export interface PatientInvoicesPayload { patient: { uuid: string; name: string | null; national_code: string | null }; data: PatientInvoiceRow[]; summary: PaymentsSummary; meta: { totalRecords: number; totalPages: number; currentPage: number }; } const LIMIT = 20; /** Node 1 — flat, paginated list of the current tenant's recorded invoices. */ export function usePayments(filters: PaymentFilters) { const qs = new URLSearchParams({ page: String(filters.page), limit: String(LIMIT) }); if (filters.national_code) qs.set('national_code', filters.national_code); if (filters.status) qs.set('status', filters.status); if (filters.from) qs.set('from', String(filters.from)); if (filters.to) qs.set('to', String(filters.to)); return useQuery>({ queryKey: ['payments', filters], queryFn: () => api.get(`/api/v1/my/billing/payments?${qs.toString()}`), // ورود دوباره به صفحه همیشه داده را تازه می‌کند (پرداخت‌ها لحظه‌ای عوض می‌شوند). refetchOnMount: 'always', }); } export interface PaymentsSummary { total_rials: number; paid_rials: number; unsettled_rials: number; invoices_count: number; } /** Summary over the same filters as the list, so the stat cards match the table. */ export function usePaymentsSummary(filters: Omit) { const qs = new URLSearchParams(); if (filters.national_code) qs.set('national_code', filters.national_code); if (filters.status) qs.set('status', filters.status); if (filters.from) qs.set('from', String(filters.from)); if (filters.to) qs.set('to', String(filters.to)); return useQuery>({ queryKey: ['payments-summary', filters], queryFn: () => api.get(`/api/v1/my/billing/payments/summary?${qs.toString()}`), refetchOnMount: 'always', }); } /** Node 2 — a single patient's recorded invoices (header + paginated list). */ export function usePatientInvoices(patientUuid: string | undefined, page: number) { return useQuery>({ queryKey: ['patient-invoices', patientUuid, page], queryFn: () => api.get(`/api/v1/my/billing/patients/${patientUuid}/invoices?page=${page}&limit=${LIMIT}`), enabled: !!patientUuid, }); } export const MY_PAYMENTS_LIMIT = LIMIT;