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:
@@ -8,7 +8,7 @@ import type { ServiceCategoryOption } from '../hooks/useServiceCategories';
|
||||
|
||||
const mkContract = (over: Partial<Contract> = {}): Contract => ({
|
||||
uuid: 'c-1', insurance_id: 3, insurance_name: 'بیمه ایران', insurance_kind: 'basic',
|
||||
version: 1, is_active: true, coverage_percent: 70, franchise_rials: 500_000,
|
||||
version: 1, is_active: true, coverage_percent: 70, franchise_percent: 15,
|
||||
annual_ceiling_rials: 20_000_000, kind: 'basic', effective_from: 1_700_000_000,
|
||||
effective_to: null,
|
||||
category_coverages: { outpatient: 70, inpatient: 30 },
|
||||
@@ -27,11 +27,11 @@ const categories: ServiceCategoryOption[] = [
|
||||
];
|
||||
|
||||
describe('buildInsurancePayload', () => {
|
||||
it('converts toman → rials, per-category percents, and Y-m-d → unix', () => {
|
||||
it('keeps the franchise a percent, converts ceiling toman → rials and Y-m-d → unix', () => {
|
||||
const payload = buildInsurancePayload({
|
||||
...EMPTY_FORM, insuranceId: '3', kind: 'supplementary',
|
||||
categoryPercents: { outpatient: '80', inpatient: '30' },
|
||||
franchise: '50000', ceiling: '2000000',
|
||||
franchise: '10', ceiling: '2000000',
|
||||
effectiveFrom: '2024-01-01', effectiveTo: '2025-01-01',
|
||||
});
|
||||
expect(payload.insurance_id).toBe(3);
|
||||
@@ -41,7 +41,7 @@ describe('buildInsurancePayload', () => {
|
||||
{ key: 'outpatient', coverage_percent: 80 },
|
||||
{ key: 'inpatient', coverage_percent: 30 },
|
||||
]);
|
||||
expect(payload.franchise_rials).toBe(500_000); // 50000 toman × 10
|
||||
expect(payload.franchise_percent).toBe(10); // درصد است، نه مبلغ
|
||||
expect(payload.annual_ceiling_rials).toBe(20_000_000);
|
||||
expect(typeof payload.effective_from).toBe('number');
|
||||
expect(payload.effective_to).toBeGreaterThan(payload.effective_from!);
|
||||
@@ -58,10 +58,10 @@ describe('buildInsurancePayload', () => {
|
||||
|
||||
it('forces franchise to zero on a basic contract', () => {
|
||||
const payload = buildInsurancePayload({
|
||||
...EMPTY_FORM, insuranceId: '3', kind: 'basic', franchise: '50000',
|
||||
...EMPTY_FORM, insuranceId: '3', kind: 'basic', franchise: '10',
|
||||
categoryPercents: { outpatient: '70' },
|
||||
});
|
||||
expect(payload.franchise_rials).toBe(0);
|
||||
expect(payload.franchise_percent).toBe(0);
|
||||
});
|
||||
|
||||
it('omits category_coverages when the user may not override them', () => {
|
||||
@@ -75,9 +75,9 @@ describe('buildInsurancePayload', () => {
|
||||
});
|
||||
|
||||
describe('contractToForm', () => {
|
||||
it('maps rials → toman, contract kind, and effective category percents', () => {
|
||||
const form = contractToForm(mkContract({ franchise_rials: 300_000, kind: 'supplementary' }));
|
||||
expect(form.franchise).toBe('30000');
|
||||
it('maps the franchise percent, contract kind, and effective category percents', () => {
|
||||
const form = contractToForm(mkContract({ franchise_percent: 30, kind: 'supplementary' }));
|
||||
expect(form.franchise).toBe('30');
|
||||
expect(form.kind).toBe('supplementary');
|
||||
expect(form.categoryPercents).toEqual({ outpatient: '70', inpatient: '30' });
|
||||
});
|
||||
@@ -95,7 +95,7 @@ describe('InsuranceModal', () => {
|
||||
expect(screen.getByText('پایه')).toBeInTheDocument();
|
||||
expect(screen.getByText('درصد پوشش — خدمات سرپایی')).toBeInTheDocument();
|
||||
expect(screen.getByText('درصد پوشش — خدمات بستری')).toBeInTheDocument();
|
||||
expect(screen.queryByText('فرانشیز (تومان)')).not.toBeInTheDocument();
|
||||
expect(screen.queryByText('فرانشیز (درصد)')).not.toBeInTheDocument();
|
||||
expect(screen.getByText('سقف تعهد (تومان)')).toBeInTheDocument();
|
||||
expect(screen.getByText('ثبت بیمه')).toBeInTheDocument();
|
||||
});
|
||||
@@ -105,7 +105,48 @@ describe('InsuranceModal', () => {
|
||||
<InsuranceModal open editContract={null} options={options} categories={categories} kind="supplementary" onClose={() => {}} onSubmit={() => {}} />,
|
||||
);
|
||||
expect(screen.getByText('تکمیلی')).toBeInTheDocument();
|
||||
expect(screen.getByText('فرانشیز (تومان)')).toBeInTheDocument();
|
||||
expect(screen.getByText('فرانشیز (درصد)')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('blocks submit until every rendered category has a valid percent', () => {
|
||||
const onSubmit = vi.fn();
|
||||
renderWithProviders(
|
||||
<InsuranceModal
|
||||
open
|
||||
editContract={mkContract({ category_coverages: { outpatient: 70 } })}
|
||||
options={options}
|
||||
categories={categories}
|
||||
kind="basic"
|
||||
onClose={() => {}}
|
||||
onSubmit={onSubmit}
|
||||
/>,
|
||||
);
|
||||
|
||||
// بستری بدون درصد مانده: ثبت باید بسته باشد و پیام الزامی دیده شود.
|
||||
expect(screen.getByText('ثبت بیمه')).toBeDisabled();
|
||||
expect(screen.getByText('درصد پوشش الزامی است (۱ تا ۱۰۰)')).toBeInTheDocument();
|
||||
|
||||
fireEvent.change(screen.getByLabelText('درصد پوشش خدمات بستری'), { target: { value: '30' } });
|
||||
expect(screen.getByText('ثبت بیمه')).not.toBeDisabled();
|
||||
|
||||
fireEvent.click(screen.getByText('ثبت بیمه'));
|
||||
expect(onSubmit).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('renders only the service kinds it is given', () => {
|
||||
renderWithProviders(
|
||||
<InsuranceModal
|
||||
open
|
||||
editContract={null}
|
||||
options={options}
|
||||
categories={[{ key: 'outpatient', label: 'خدمات سرپایی' }]}
|
||||
kind="basic"
|
||||
onClose={() => {}}
|
||||
onSubmit={() => {}}
|
||||
/>,
|
||||
);
|
||||
expect(screen.getByText('درصد پوشش — خدمات سرپایی')).toBeInTheDocument();
|
||||
expect(screen.queryByText('درصد پوشش — خدمات بستری')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('prefills the percents of an edited contract and marks admin defaults', () => {
|
||||
@@ -132,7 +173,7 @@ describe('InsuranceModal', () => {
|
||||
);
|
||||
fireEvent.click(screen.getByText('ثبت بیمه'));
|
||||
expect(onSubmit).toHaveBeenCalledWith(expect.objectContaining({
|
||||
insurance_id: 3, coverage_percent: 70, franchise_rials: 0, kind: 'basic',
|
||||
insurance_id: 3, coverage_percent: 70, franchise_percent: 0, kind: 'basic',
|
||||
category_coverages: [
|
||||
{ key: 'outpatient', coverage_percent: 70 },
|
||||
{ key: 'inpatient', coverage_percent: 30 },
|
||||
|
||||
Reference in New Issue
Block a user