104 lines
3.7 KiB
TypeScript
104 lines
3.7 KiB
TypeScript
/* eslint-disable sonarjs/cognitive-complexity */
|
|
import { debouncedReaction } from '../utils/mobx';
|
|
import type { ProcessContext } from './types';
|
|
import type { Elements } from '@/Components/Calculation/config/map/values';
|
|
import type { Values } from '@/stores/calculation/values/types';
|
|
import ValidationHelper from '@/stores/validation/helper';
|
|
import { comparer, toJS } from 'mobx';
|
|
import { uid } from 'radash';
|
|
import type { ZodTypeAny } from 'zod';
|
|
|
|
export function createValidationReaction<T extends ZodTypeAny>(
|
|
createValidationSchema: (context: ProcessContext) => T,
|
|
opts?: { fireImmediately: boolean }
|
|
) {
|
|
const key = uid(7);
|
|
|
|
return (context: ProcessContext) => {
|
|
const validationSchema = createValidationSchema(context);
|
|
const shapeValues = Object.keys(validationSchema._def.schema.shape) as string[];
|
|
|
|
const { store } = context;
|
|
const { $calculation, $tables } = store;
|
|
|
|
const helper = new ValidationHelper();
|
|
|
|
debouncedReaction(
|
|
() => {
|
|
const values = $calculation.$values.getValues(shapeValues as Values[]);
|
|
if (shapeValues.includes('insurance'))
|
|
return {
|
|
...values,
|
|
fingap: $tables.fingap.getSelectedRisks(),
|
|
insurance: {
|
|
values: {
|
|
fingap: toJS($tables.insurance.row('fingap').getValues()),
|
|
kasko: toJS($tables.insurance.row('kasko').getValues()),
|
|
osago: toJS($tables.insurance.row('osago').getValues()),
|
|
},
|
|
},
|
|
};
|
|
|
|
if (shapeValues.includes('payments')) {
|
|
return {
|
|
...values,
|
|
payments: { values: toJS($tables.payments.values) },
|
|
};
|
|
}
|
|
|
|
return values;
|
|
},
|
|
async (values) => {
|
|
helper.removeErrors();
|
|
const validationResult = await validationSchema.safeParseAsync(values);
|
|
|
|
if (validationResult.success === false) {
|
|
validationResult.error.errors.forEach(({ path, message }) => {
|
|
(
|
|
path as Array<
|
|
Elements & ('eltKasko' | 'eltOsago' | 'fingap' | 'insurance' | 'payments')
|
|
>
|
|
).forEach((elementName) => {
|
|
if (elementName === 'insurance') {
|
|
const removeError = $tables.insurance.setError({ key, message });
|
|
if (removeError) helper.add(removeError);
|
|
} else if (elementName === 'fingap') {
|
|
const removeError = $tables.fingap.setError({ key, message });
|
|
if (removeError) helper.add(removeError);
|
|
} else if (elementName === 'payments') {
|
|
const removeError = $tables.payments.setError({ key, message });
|
|
if (removeError) helper.add(removeError);
|
|
} else if (elementName === 'eltOsago') {
|
|
const removeError = $tables.elt.osago.validation.setError({
|
|
key,
|
|
message,
|
|
silent: true,
|
|
});
|
|
if (removeError) helper.add(removeError);
|
|
} else if (elementName === 'eltKasko') {
|
|
const removeError = $tables.elt.kasko.validation.setError({
|
|
key,
|
|
message,
|
|
silent: true,
|
|
});
|
|
if (removeError) helper.add(removeError);
|
|
} else {
|
|
const removeError = $calculation.element(elementName).setError({ key, message });
|
|
if (removeError) helper.add(removeError);
|
|
}
|
|
});
|
|
});
|
|
} else {
|
|
helper.removeErrors();
|
|
}
|
|
},
|
|
{
|
|
delay: 1,
|
|
equals: comparer.structural,
|
|
fireImmediately: opts?.fireImmediately,
|
|
wait: 100,
|
|
}
|
|
);
|
|
};
|
|
}
|