From 5a78a0f9098cb1ee5d65e678ee1f12b26b08b21a Mon Sep 17 00:00:00 2001 From: vchikalkin Date: Thu, 13 Apr 2023 12:15:10 +0300 Subject: [PATCH] process/add-product: create validation --- apps/web/process/add-product/index.ts | 1 + apps/web/process/add-product/reactions.ts | 116 ++++++++++++++++++ apps/web/process/add-product/validation.ts | 28 +++++ apps/web/process/recalc/reactions.ts | 75 +---------- .../routers/calculate/lib/validation.ts | 2 + 5 files changed, 148 insertions(+), 74 deletions(-) create mode 100644 apps/web/process/add-product/validation.ts diff --git a/apps/web/process/add-product/index.ts b/apps/web/process/add-product/index.ts index e05ea2d..2bcf57b 100644 --- a/apps/web/process/add-product/index.ts +++ b/apps/web/process/add-product/index.ts @@ -1,2 +1,3 @@ export * from './get-kp-data'; export * as reactions from './reactions'; +export * from './validation'; diff --git a/apps/web/process/add-product/reactions.ts b/apps/web/process/add-product/reactions.ts index 7d83383..c51e731 100644 --- a/apps/web/process/add-product/reactions.ts +++ b/apps/web/process/add-product/reactions.ts @@ -1,9 +1,16 @@ import type { ProcessContext } from '../types'; +import { createValidationSchema } from './validation'; +import type { Elements } from '@/Components/Calculation/config/map/values'; +import { selectRequirementTelematic } from '@/config/default-options'; import * as CRMTypes from '@/graphql/crm.types'; +import type { Values } from '@/stores/calculation/values/types'; +import ValidationHelper from '@/stores/validation/helper'; import { normalizeOptions } from '@/utils/entity'; +import { debouncedReaction } from '@/utils/mobx'; import dayjs from 'dayjs'; import utc from 'dayjs/plugin/utc'; import { reaction } from 'mobx'; +import { uid } from 'radash'; dayjs.extend(utc); @@ -117,4 +124,113 @@ export default function reactions({ store, apolloClient }: ProcessContext) { fireImmediately: true, } ); + + reaction( + () => $calculation.$values.getValues(['recalcWithRevision', 'leaseObjectType']), + async ({ recalcWithRevision, leaseObjectType: leaseObjectTypeId }) => { + if (recalcWithRevision === false) { + $calculation + .element('selectRequirementTelematic') + .setOptions( + selectRequirementTelematic.filter((x) => + [100_000_000, 100_000_001, 100_000_002, 100_000_003].includes(x.value) + ) + ); + + if (leaseObjectTypeId) { + const { + data: { evo_leasingobject_type }, + } = await apolloClient.query({ + query: CRMTypes.GetLeaseObjectTypeDocument, + variables: { leaseObjectTypeId }, + }); + + if (evo_leasingobject_type?.evo_id === '11') { + $calculation.element('selectRequirementTelematic').setValue(100_000_000).block(); + } else { + $calculation.element('selectRequirementTelematic').unblock(); + } + } + } else { + $calculation.element('selectRequirementTelematic').resetOptions(); + } + }, + { + fireImmediately: true, + } + ); + + reaction( + () => $calculation.$values.getValues(['requirementTelematic', 'recalcWithRevision']), + async ({ requirementTelematic, recalcWithRevision }) => { + const currentDate = dayjs().utc(false).format('YYYY-MM-DD'); + const { + data: { evo_addproduct_types: trackerTypes }, + } = await apolloClient.query({ + query: CRMTypes.GetTrackerTypesDocument, + variables: { currentDate }, + }); + + const { + data: { evo_addproduct_types: telematicTypes }, + } = await apolloClient.query({ + query: CRMTypes.GetTelematicTypesDocument, + variables: { currentDate }, + }); + + let filteredTrackerTypes = trackerTypes?.filter( + (x) => requirementTelematic && x?.evo_controls_program?.includes(requirementTelematic) + ); + + let filteredTelematicTypes = telematicTypes?.filter( + (x) => requirementTelematic && x?.evo_controls_program?.includes(requirementTelematic) + ); + + if (!recalcWithRevision) { + filteredTrackerTypes = filteredTrackerTypes?.filter((x) => x?.evo_visible_calc === true); + filteredTelematicTypes = filteredTelematicTypes?.filter( + (x) => x?.evo_visible_calc === true + ); + } + + $calculation.element('selectTracker').setOptions(normalizeOptions(filteredTrackerTypes)); + $calculation.element('selectTelematic').setOptions(normalizeOptions(filteredTelematicTypes)); + }, + { + fireImmediately: true, + } + ); +} + +const key = uid(7); + +export function validation(context: ProcessContext) { + const { store } = context; + const { $calculation } = store; + const validationSchema = createValidationSchema(context); + + const helper = new ValidationHelper(); + debouncedReaction( + () => + $calculation.$values.getValues(Object.keys(validationSchema._def.schema.shape) as Values[]), + async (values) => { + helper.removeErrors(); + const validationResult = await validationSchema.safeParseAsync(values); + + if (validationResult.success === false) { + validationResult.error.errors.forEach(({ path, message }) => { + (path as Elements[]).forEach((elementName) => { + const removeError = $calculation.element(elementName).setError({ key, message }); + if (removeError) helper.add(removeError); + }); + }); + } else { + helper.removeErrors(); + } + }, + { + delay: 1, + wait: 100, + } + ); } diff --git a/apps/web/process/add-product/validation.ts b/apps/web/process/add-product/validation.ts new file mode 100644 index 0000000..0ee7a4e --- /dev/null +++ b/apps/web/process/add-product/validation.ts @@ -0,0 +1,28 @@ +import type { ValidationContext } from '../types'; +import ValuesSchema from '@/config/schema/values'; +import { z } from 'zod'; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +export function createValidationSchema(context: ValidationContext) { + return ValuesSchema.pick({ + requirementTelematic: true, + telematic: true, + tracker: true, + }).superRefine(async ({ requirementTelematic, telematic, tracker }, ctx) => { + if (requirementTelematic !== 100_000_004 && !telematic && !tracker) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: 'Не заполнено поле', + path: ['selectTracker', 'selectTelematic'], + }); + } + + if (requirementTelematic === 100_000_004 && (telematic || tracker)) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: 'Не требуется', + path: ['selectTracker', 'selectTelematic'], + }); + } + }); +} diff --git a/apps/web/process/recalc/reactions.ts b/apps/web/process/recalc/reactions.ts index bedab4b..f6c9f93 100644 --- a/apps/web/process/recalc/reactions.ts +++ b/apps/web/process/recalc/reactions.ts @@ -1,11 +1,8 @@ import type { ProcessContext } from '../types'; import { createValidationSchema } from './validation'; import type { Elements } from '@/Components/Calculation/config/map/values'; -import { selectRequirementTelematic } from '@/config/default-options'; -import * as CRMTypes from '@/graphql/crm.types'; import type { Values } from '@/stores/calculation/values/types'; import ValidationHelper from '@/stores/validation/helper'; -import { normalizeOptions } from '@/utils/entity'; import { debouncedReaction, disposableReaction } from '@/utils/mobx'; import dayjs from 'dayjs'; import utc from 'dayjs/plugin/utc'; @@ -14,7 +11,7 @@ import { uid } from 'radash'; dayjs.extend(utc); -export function common({ store, apolloClient }: ProcessContext) { +export function common({ store }: ProcessContext) { const { $calculation, $tables } = store; reaction( @@ -56,76 +53,6 @@ export function common({ store, apolloClient }: ProcessContext) { } ); - reaction( - () => $calculation.$values.getValues(['recalcWithRevision', 'leaseObjectType']), - async ({ recalcWithRevision, leaseObjectType: leaseObjectTypeId }) => { - if (recalcWithRevision === false) { - $calculation - .element('selectRequirementTelematic') - .setOptions( - selectRequirementTelematic.filter((x) => - [100_000_000, 100_000_001, 100_000_002, 100_000_003].includes(x.value) - ) - ); - - if (leaseObjectTypeId) { - const { - data: { evo_leasingobject_type }, - } = await apolloClient.query({ - query: CRMTypes.GetLeaseObjectTypeDocument, - variables: { leaseObjectTypeId }, - }); - - if (evo_leasingobject_type?.evo_id === '11') { - $calculation.element('selectRequirementTelematic').setValue(100_000_000).block(); - } else { - $calculation.element('selectRequirementTelematic').unblock(); - } - } - } else { - $calculation.element('selectRequirementTelematic').resetOptions(); - } - } - ); - - reaction( - () => $calculation.$values.getValues(['requirementTelematic', 'recalcWithRevision']), - async ({ requirementTelematic, recalcWithRevision }) => { - const currentDate = dayjs().utc(false).format('YYYY-MM-DD'); - const { - data: { evo_addproduct_types: trackerTypes }, - } = await apolloClient.query({ - query: CRMTypes.GetTrackerTypesDocument, - variables: { currentDate }, - }); - - const { - data: { evo_addproduct_types: telematicTypes }, - } = await apolloClient.query({ - query: CRMTypes.GetTelematicTypesDocument, - variables: { currentDate }, - }); - - let filteredTrackerTypes = trackerTypes?.filter( - (x) => requirementTelematic && x?.evo_controls_program?.includes(requirementTelematic) - ); - - let filteredTelematicTypes = telematicTypes?.filter( - (x) => requirementTelematic && x?.evo_controls_program?.includes(requirementTelematic) - ); - - if (!recalcWithRevision) { - filteredTrackerTypes = filteredTrackerTypes?.filter((x) => x?.evo_visible_calc === true); - filteredTelematicTypes = filteredTelematicTypes?.filter( - (x) => x?.evo_visible_calc === true - ); - } - - $calculation.element('selectTracker').setOptions(normalizeOptions(filteredTrackerTypes)); - $calculation.element('selectTelematic').setOptions(normalizeOptions(filteredTelematicTypes)); - } - ); - { const elements: Elements[] = [ 'cbxLeaseObjectUsed', diff --git a/apps/web/server/routers/calculate/lib/validation.ts b/apps/web/server/routers/calculate/lib/validation.ts index 77ced81..87c055a 100644 --- a/apps/web/server/routers/calculate/lib/validation.ts +++ b/apps/web/server/routers/calculate/lib/validation.ts @@ -1,6 +1,7 @@ import type { CalculateInput, Context } from '../types'; import elementsTitles from '@/Components/Calculation/config/elements-titles'; import type { Elements } from '@/Components/Calculation/config/map/values'; +import * as addProduct from '@/process/add-product'; import * as bonuses from '@/process/bonuses'; import * as configurator from '@/process/configurator'; import * as gibdd from '@/process/gibdd'; @@ -20,6 +21,7 @@ const processes = [ leasingObject, gibdd, insuranceProcess, + addProduct, ]; const titles = Object.assign(elementsTitles, {