process/insurance: use new validation

This commit is contained in:
vchikalkin 2023-03-07 13:05:55 +03:00
parent 81517212fb
commit 54004173ae
4 changed files with 135 additions and 81 deletions

View File

@ -6,7 +6,7 @@ import * as configurator from '@/process/configurator';
import * as fingap from '@/process/fingap';
import * as gibdd from '@/process/gibdd';
import { useProcess } from '@/process/hooks';
// import * as insurance from '@/process/insurance';
import * as insurance from '@/process/insurance';
// import * as leadOpportunity from '@/process/lead-opportunity';
// import * as leasingObject from '@/process/leasing-object';
// import * as leasingWithoutKasko from '@/process/leasing-without-kasko';
@ -36,5 +36,5 @@ export default function useReactions() {
useProcess(payments);
useProcess(gibdd);
// useProcess(addProduct);
// useProcess(insurance);
useProcess(insurance);
}

View File

@ -1,14 +1,16 @@
/* eslint-disable @typescript-eslint/naming-convention */
import type { ProcessContext } from '../types';
import { createValidationSchema } from './validation';
import { normalizeOptions } from '@/../../packages/tools';
import type * as Insurance from '@/Components/Calculation/Form/Insurance/InsuranceTable/types';
import type { Elements } from '@/Components/Calculation/config/map/values';
import { selectLeaseObjectUseFor } from '@/config/default-options';
import * as CRMTypes from '@/graphql/crm.types';
import ValidationHelper from '@/stores/validation/helper';
import { reaction } from 'mobx';
import { comparer, reaction, toJS } from 'mobx';
import { uid } from 'radash';
export function common({ store, apolloClient }: ProcessContext) {
const { $calculation, $tables } = store;
const { $calculation } = store;
reaction(
() => $calculation.element('selectGPSBrand').getValue(),
@ -113,75 +115,52 @@ export function common({ store, apolloClient }: ProcessContext) {
);
}
export function validation({ store, apolloClient }: ProcessContext) {
const { $calculation, $tables } = store;
const key = uid(7);
{
const validationHelper = new ValidationHelper();
reaction(
() => ({
insTerm: $tables.insurance.row('kasko').getValue('insTerm'),
...$calculation.$values.getValues(['leasingPeriod', 'recalcWithRevision', 'quote']),
}),
async ({ leasingPeriod, insTerm, recalcWithRevision, quote: quoteId }) => {
if (!quoteId) {
validationHelper.removeErrors();
export function validation(context: ProcessContext) {
const { $calculation, $tables } = context.store;
return;
}
const validationSchema = createValidationSchema(context);
const helper = new ValidationHelper();
const {
data: { quote },
} = await apolloClient.query({
query: CRMTypes.GetQuoteDocument,
variables: { quoteId },
});
reaction(
() => {
const values = $calculation.$values.getValues([
'leasingPeriod',
'quote',
'recalcWithRevision',
]);
$tables.insurance.validate({
helper: validationHelper,
invalid:
recalcWithRevision &&
quote?.evo_one_year_insurance === true &&
leasingPeriod > 15 &&
insTerm === 100_000_001,
message:
'Срок страхования КАСКО должен быть 12 месяцев, т.к. оформляется Однолетний полис',
return {
insurance: {
fingap: toJS($tables.insurance.row('fingap').getValues()),
kasko: toJS($tables.insurance.row('kasko').getValues()),
osago: toJS($tables.insurance.row('osago').getValues()),
},
...values,
};
},
async (values) => {
helper.removeErrors();
const validationResult = await validationSchema.safeParseAsync(values);
if (!validationResult.success) {
validationResult.error.errors.forEach(({ path, message }) => {
(path as Array<Elements & 'insurance'>).forEach((elementName) => {
if (elementName === 'insurance') {
const removeError = $tables.insurance.setError({ key, message });
if (removeError) helper.add(removeError);
} else {
const removeError = $calculation.element(elementName).setError({ key, message });
if (removeError) helper.add(removeError);
}
});
});
}
);
}
(['osago', 'kasko'] as Insurance.Keys[]).forEach((key) => {
const validationHelper = new ValidationHelper();
reaction(
() => $tables.insurance.row(key).getValues(),
({ insCost, insured, policyType, insuranceCompany, insTerm }) => {
validationHelper.removeErrors();
$tables.insurance.validate({
helper: validationHelper,
invalid: insCost === 0 && insured === 100_000_001,
message: `Укажите стоимость ${policyType}, включаемую в график`,
});
$tables.insurance.validate({
helper: validationHelper,
invalid: insCost > 0 && !insuranceCompany,
message: `Укажите страховую компанию ${policyType}`,
});
$tables.insurance.validate({
helper: validationHelper,
invalid: insCost > 0 && !insTerm,
message: `Укажите срок страхования ${policyType}`,
});
$tables.insurance.validate({
helper: validationHelper,
invalid: insCost > 0 && !insured,
message: `Укажите плательщика ${policyType}`,
});
}
);
});
},
{
delay: 50,
equals: comparer.structural,
}
);
}

View File

@ -0,0 +1,82 @@
import type { ValidationContext } from '../types';
import type * as Insurance from '@/Components/Calculation/Form/Insurance/InsuranceTable/types';
import { RowSchema } from '@/config/schema/insurance';
import ValuesSchema from '@/config/schema/values';
import * as CRMTypes from '@/graphql/crm.types';
import { z } from 'zod';
export function createValidationSchema({ apolloClient }: ValidationContext) {
return ValuesSchema.pick({
leasingPeriod: true,
quote: true,
recalcWithRevision: true,
})
.extend({
insurance: z
.object({
fingap: RowSchema,
kasko: RowSchema,
osago: RowSchema,
})
.strict(),
})
.superRefine(async ({ leasingPeriod, recalcWithRevision, quote: quoteId, insurance }, ctx) => {
if (quoteId) {
const {
data: { quote },
} = await apolloClient.query({
query: CRMTypes.GetQuoteDocument,
variables: { quoteId },
});
if (
recalcWithRevision &&
quote?.evo_one_year_insurance === true &&
leasingPeriod > 15 &&
insurance.kasko.insTerm === 100_000_001
) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message:
'Срок страхования КАСКО должен быть 12 месяцев, т.к. оформляется Однолетний полис',
path: ['insurance'],
});
}
}
(['osago', 'kasko'] as Insurance.Keys[]).forEach((key) => {
const { insCost, insured, policyType, insuranceCompany, insTerm } = insurance[key];
if (insCost === 0 && insured === 100_000_001) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `Укажите стоимость ${policyType}, включаемую в график`,
path: ['insurance'],
});
}
if (insCost > 0 && !insuranceCompany) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `Укажите страховую компанию ${policyType}`,
path: ['insurance'],
});
}
if (insCost > 0 && !insTerm) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `Укажите срок страхования ${policyType}`,
path: ['insurance'],
});
}
if (insCost > 0 && !insured) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `Укажите плательщика ${policyType}`,
path: ['insurance'],
});
}
});
});
}

View File

@ -1,5 +1,5 @@
import Validation from '../../validation';
import type { RemoveError, ValidationParams } from '../../validation/types';
import type { ValidationParams } from '../../validation/types';
import type * as Insurance from '@/Components/Calculation/Form/Insurance/InsuranceTable/types';
import * as insuranceTableConfig from '@/config/tables/insurance-table';
import type RootStore from '@/stores/root';
@ -40,17 +40,10 @@ export default class InsuranceTable {
if (initialStatuses) this.statuses = initialStatuses;
};
public validate = ({ invalid, message, helper }: ValidationParams) => {
let removeError: RemoveError | undefined;
public setError = (params: ValidationParams) => this.validation.setError(params);
if (invalid) {
removeError = this.validation?.addError(message);
if (helper && removeError) helper.add(removeError);
} else {
this.validation?.removeError(message);
}
return removeError;
public removeError = (params: Pick<ValidationParams, 'key'>) => {
this.validation.removeError(params);
};
public reset = () => {