feat(migrations): update franchise to percentage in tenant_insurances and tenant_service_coverage
- Changed franchise_rials to franchise_percent in tenant_insurances and tenant_service_coverage tables. - Reset old rial values to 0/NULL as they are not convertible to percentage. feat(command): add SeedInsuranceScenarioCommand for seeding insurance data - Implemented a command to seed supplementary insurance contracts, patients, and claims for a specified doctor. - Includes functionality for purging existing scenario data and generating new entries with predefined contracts and patient scenarios.
This commit is contained in:
@@ -32,6 +32,15 @@ const PAYMENT_OPTIONS = [
|
||||
{ value: 'unpaid', label: 'وصولنشده' },
|
||||
];
|
||||
|
||||
/** واژگان مطالبه `base` است، نه `basic` که در قرارداد بیمه به کار میرود. */
|
||||
const KIND_OPTIONS = [
|
||||
{ value: '', label: 'همه انواع' },
|
||||
{ value: 'base', label: 'پایه' },
|
||||
{ value: 'supplementary', label: 'تکمیلی' },
|
||||
];
|
||||
|
||||
const KIND_LABEL: Record<string, string> = { base: 'پایه', supplementary: 'تکمیلی' };
|
||||
|
||||
const isoNDaysAgo = (days: number): string => {
|
||||
const d = new Date();
|
||||
d.setDate(d.getDate() - days);
|
||||
@@ -69,6 +78,7 @@ export default function ClaimsPage() {
|
||||
const search = params.get('search') ?? '';
|
||||
const status = params.get('status') ?? '';
|
||||
const insuranceId = params.get('insurance_id') ?? '';
|
||||
const kind = params.get('kind') ?? '';
|
||||
const paymentStatus = params.get('payment_status') ?? '';
|
||||
const from = params.get('from') ?? '';
|
||||
const to = params.get('to') ?? '';
|
||||
@@ -76,7 +86,7 @@ export default function ClaimsPage() {
|
||||
const sort = params.get('sort') ?? 'last_activity_at';
|
||||
const dir = (params.get('dir') ?? 'desc') as 'asc' | 'desc';
|
||||
|
||||
const hasFilters = !!(search || status || insuranceId || paymentStatus || from || to);
|
||||
const hasFilters = !!(search || status || insuranceId || kind || paymentStatus || from || to);
|
||||
|
||||
/** تغییر فیلتر همیشه به صفحهی اول برمیگردد؛ ماندن روی صفحه ۵ با نتیجهی جدید بیمعناست. */
|
||||
const setParam = (patch: Record<string, string>) => {
|
||||
@@ -95,13 +105,14 @@ export default function ClaimsPage() {
|
||||
if (search) qs.set('search', search);
|
||||
if (status) qs.set('status', status);
|
||||
if (insuranceId) qs.set('insurance_id', insuranceId);
|
||||
if (kind) qs.set('kind', kind);
|
||||
if (paymentStatus) qs.set('payment_status', paymentStatus);
|
||||
const fromUnix = toUnix(from);
|
||||
const toUnixVal = endOfDayUnix(to);
|
||||
if (fromUnix) qs.set('from', String(fromUnix));
|
||||
if (toUnixVal) qs.set('to', String(toUnixVal));
|
||||
return qs.toString();
|
||||
}, [page, sort, dir, search, status, insuranceId, paymentStatus, from, to]);
|
||||
}, [page, sort, dir, search, status, insuranceId, kind, paymentStatus, from, to]);
|
||||
|
||||
const listQuery = useQuery<PaginatedResponse<ClaimPatientRow>>({
|
||||
queryKey: ['claims-by-patient', queryString],
|
||||
@@ -142,6 +153,25 @@ export default function ClaimsPage() {
|
||||
{ key: 'full_name', header: 'بیمار', sortable: true, render: (r) => r.full_name ?? '—' },
|
||||
{ key: 'mobile', header: 'موبایل', render: (r) => r.mobile ?? '—' },
|
||||
{ key: 'national_code', header: 'کد ملی', render: (r) => r.national_code ?? '—' },
|
||||
{
|
||||
key: 'insurances',
|
||||
header: 'بیمه',
|
||||
render: (r) => (
|
||||
(r.insurances ?? []).length === 0 ? '—' : (
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 4 }}>
|
||||
{r.insurances.map((i) => (
|
||||
<span
|
||||
key={`${i.insurance_id}-${i.kind}`}
|
||||
className={`badge ${i.kind === 'supplementary' ? 'violet' : 'blue'}`}
|
||||
title={KIND_LABEL[i.kind ?? ''] ?? i.kind ?? ''}
|
||||
>
|
||||
{i.insurance_name ?? `بیمه #${i.insurance_id}`}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
),
|
||||
},
|
||||
{ key: 'claims_count', header: 'تعداد درخواست', sortable: true, render: (r) => formatNumber(r.claims_count) },
|
||||
{ key: 'total_services_rials', header: 'مجموع خدمات', sortable: true, render: (r) => formatRial(r.total_services_rials) },
|
||||
{ key: 'total_insurance_rials', header: 'سهم بیمه', sortable: true, render: (r) => formatRial(r.total_insurance_rials) },
|
||||
@@ -176,6 +206,16 @@ export default function ClaimsPage() {
|
||||
height={38}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ minWidth: 130 }}>
|
||||
<label className="field-label">نوع بیمه</label>
|
||||
<SearchableSelect
|
||||
options={KIND_OPTIONS}
|
||||
value={kind}
|
||||
onChange={(v) => setParam({ kind: v ? String(v) : '' })}
|
||||
placeholder="همه انواع"
|
||||
height={38}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ minWidth: 150 }}>
|
||||
<label className="field-label">وضعیت</label>
|
||||
<SearchableSelect
|
||||
@@ -225,7 +265,7 @@ export default function ClaimsPage() {
|
||||
loading={listQuery.isLoading}
|
||||
searchValue={search}
|
||||
onSearchChange={(v) => setParam({ search: v })}
|
||||
searchPlaceholder="نام، موبایل یا کد ملی بیمار"
|
||||
searchPlaceholder="نام، موبایل، کد ملی بیمار یا نام بیمه"
|
||||
emptyMessage="پرونده بیمهای ثبت نشده است."
|
||||
sortKey={sort}
|
||||
sortDir={dir}
|
||||
|
||||
Reference in New Issue
Block a user