diff --git a/apps/web/config/process/default.ts b/apps/web/config/process/default.ts index 4cb4fe8..4acd219 100644 --- a/apps/web/config/process/default.ts +++ b/apps/web/config/process/default.ts @@ -4,7 +4,7 @@ import * as bonuses from '@/process/bonuses'; import * as configurator from '@/process/configurator'; // import * as createKP from '@/process/create-kp'; import * as fingap from '@/process/fingap'; -// import * as gibdd from '@/process/gibdd'; +import * as gibdd from '@/process/gibdd'; import { useProcess } from '@/process/hooks'; // import * as insurance from '@/process/insurance'; // import * as leadOpportunity from '@/process/lead-opportunity'; @@ -34,7 +34,7 @@ export default function useReactions() { // useProcess(usedPl); // useProcess(subsidyImportProgram); useProcess(payments); - // useProcess(gibdd); + useProcess(gibdd); // useProcess(addProduct); // useProcess(insurance); } diff --git a/apps/web/constants/values.js b/apps/web/constants/values.js index ae2d4ca..979db7d 100644 --- a/apps/web/constants/values.js +++ b/apps/web/constants/values.js @@ -7,3 +7,4 @@ export const MAX_LEASING_PERIOD = 60; export const MIN_LASTPAYMENT_NSIB = 3500; export const MIN_PAYMENT = 3; export const VAT = 0.2; +export const MAX_MASS = 3500; diff --git a/apps/web/process/gibdd/reactions.ts b/apps/web/process/gibdd/reactions.ts index b9326c0..c17b513 100644 --- a/apps/web/process/gibdd/reactions.ts +++ b/apps/web/process/gibdd/reactions.ts @@ -1,7 +1,9 @@ /* eslint-disable @typescript-eslint/naming-convention */ import type { ProcessContext } from '../types'; import helper from './lib/helper'; +import { createValidationSchema } from './validation'; import { getTransTax } from '@/api/1c/query'; +import type { Elements } from '@/Components/Calculation/config/map/values'; import { selectObjectCategoryTax } from '@/config/default-options'; import { STALE_TIME } from '@/constants/request'; import * as CRMTypes from '@/graphql/crm.types'; @@ -10,6 +12,7 @@ import type { QueryFunctionContext } from '@tanstack/react-query'; import dayjs from 'dayjs'; import utc from 'dayjs/plugin/utc'; import { reaction } from 'mobx'; +import { uid } from 'radash'; import { makeDisposable, normalizeOptions } from 'tools'; dayjs.extend(utc); @@ -43,36 +46,6 @@ export function common({ store, apolloClient, queryClient }: ProcessContext) { } ); - reaction( - () => $calculation.$values.getValues(['objectRegistration', 'vehicleTaxInYear']), - ({ objectRegistration, vehicleTaxInYear }) => { - if (objectRegistration === 100_000_001) { - $calculation.element('tbxVehicleTaxInYear').unblock(); - } else { - $calculation.element('tbxVehicleTaxInYear').resetValue().block(); - } - $calculation.element('tbxVehicleTaxInYear').validate({ - invalid: objectRegistration === 100_000_001 && !(vehicleTaxInYear > 0), - message: 'Значение должно быть больше 0', - }); - } - ); - - reaction( - () => $calculation.$values.getValues(['objectRegistration', 'typePTS']), - ({ objectRegistration, typePTS }) => { - if (objectRegistration === 100_000_001) { - $calculation.element('radioTypePTS').unblock(); - } else { - $calculation.element('radioTypePTS').resetValue().block(); - } - $calculation.element('radioTypePTS').validate({ - invalid: objectRegistration === 100_000_001 && !typePTS, - message: 'Не заполнено поле', - }); - } - ); - makeDisposable( () => reaction( @@ -503,89 +476,38 @@ export function common({ store, apolloClient, queryClient }: ProcessContext) { ); } -export function validation({ store, apolloClient }: ProcessContext) { - const { $calculation } = store; +const key = uid(7); +export function validation(context: ProcessContext) { + const { store } = context; + const { $calculation } = store; + const validationSchema = createValidationSchema(context); + + const validationHelper = new ValidationHelper(); reaction( - () => $calculation.$values.getValues(['leaseObjectCategory', 'maxMass']), - ({ leaseObjectCategory, maxMass }) => { - $calculation.element('tbxMaxMass').validate({ - invalid: leaseObjectCategory === 100_000_001 && maxMass > 3500, - message: 'При категории ТС = В Разрешенная макс.масса не может быть больше 3500 кг', - }); - $calculation.element('tbxMaxMass').validate({ - invalid: leaseObjectCategory === 100_000_002 && maxMass <= 3500, - message: 'При категории ТС = С Разрешенная макс.масса не может быть меньше 3500 кг', - }); + () => + $calculation.$values.getValues([ + 'leaseObjectCategory', + 'maxMass', + 'leaseObjectType', + 'typePTS', + 'objectRegistration', + 'objectCategoryTax', + 'insNSIB', + 'vehicleTaxInYear', + ]), + async (values) => { + validationHelper.removeErrors(); + const validationResult = await validationSchema.safeParseAsync(values); + + if (!validationResult.success) { + validationResult.error.errors.forEach(({ path, message }) => { + (path as Elements[]).forEach((elementName) => { + const removeError = $calculation.element(elementName).setError({ key, message }); + if (removeError) validationHelper.add(removeError); + }); + }); + } } ); - - { - const validationHelper = new ValidationHelper(); - reaction( - () => - $calculation.$values.getValues([ - 'typePTS', - 'objectRegistration', - 'objectCategoryTax', - 'leaseObjectType', - ]), - async ({ - leaseObjectType: leaseObjectTypeId, - typePTS, - objectRegistration, - objectCategoryTax, - }) => { - if (!leaseObjectTypeId) { - validationHelper.removeErrors(); - - return; - } - - const { - data: { evo_leasingobject_type }, - } = await apolloClient.query({ - query: CRMTypes.GetLeaseObjectTypeDocument, - variables: { leaseObjectTypeId }, - }); - - $calculation.element('selectObjectCategoryTax').validate({ - helper: validationHelper, - invalid: - objectRegistration === 100_000_001 && - typePTS === 100_000_001 && - objectCategoryTax === null && - Boolean(evo_leasingobject_type?.evo_category_tr?.length), - message: 'Необходимо из ЭПТС указать Категорию в соответствии с ТР ТС 018/2011', - }); - } - ); - } - - { - const validationHelper = new ValidationHelper(); - reaction( - () => $calculation.$values.getValues(['leaseObjectType', 'insNSIB']), - async ({ insNSIB, leaseObjectType: leaseObjectTypeId }) => { - if (!leaseObjectTypeId) { - validationHelper.removeErrors(); - - return; - } - - const { - data: { evo_leasingobject_type }, - } = await apolloClient.query({ - query: CRMTypes.GetLeaseObjectTypeDocument, - variables: { leaseObjectTypeId }, - }); - - $calculation.element('selectInsNSIB').validate({ - helper: validationHelper, - invalid: evo_leasingobject_type?.evo_id === '11' && !insNSIB, - message: 'Страхование НСИБ обязательно для мотоциклистов', - }); - } - ); - } } diff --git a/apps/web/process/gibdd/validation.ts b/apps/web/process/gibdd/validation.ts new file mode 100644 index 0000000..e1c90c6 --- /dev/null +++ b/apps/web/process/gibdd/validation.ts @@ -0,0 +1,95 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import type { ValidationContext } from '../types'; +import ValuesSchema from '@/config/schema/values'; +import { MAX_MASS } from '@/constants/values'; +import * as CRMTypes from '@/graphql/crm.types'; +import { z } from 'zod'; + +export function createValidationSchema({ apolloClient }: ValidationContext) { + return ValuesSchema.pick({ + insNSIB: true, + leaseObjectCategory: true, + leaseObjectType: true, + maxMass: true, + objectCategoryTax: true, + objectRegistration: true, + typePTS: true, + vehicleTaxInYear: true, + }).superRefine( + async ( + { + leaseObjectCategory, + maxMass, + leaseObjectType: leaseObjectTypeId, + typePTS, + objectRegistration, + objectCategoryTax, + insNSIB, + vehicleTaxInYear, + }, + ctx + ) => { + if (leaseObjectCategory === 100_000_001 && maxMass > MAX_MASS) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: `При категории ТС = В Разрешенная макс.масса не может быть больше ${MAX_MASS} кг`, + path: ['tbxMaxMass'], + }); + } + + if (leaseObjectCategory === 100_000_002 && maxMass <= MAX_MASS) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: `При категории ТС = С Разрешенная макс.масса не может быть меньше ${MAX_MASS} кг`, + path: ['tbxMaxMass'], + }); + } + + if (leaseObjectTypeId) { + const { + data: { evo_leasingobject_type }, + } = await apolloClient.query({ + query: CRMTypes.GetLeaseObjectTypeDocument, + variables: { leaseObjectTypeId }, + }); + + if ( + objectRegistration === 100_000_001 && + typePTS === 100_000_001 && + objectCategoryTax === null && + Boolean(evo_leasingobject_type?.evo_category_tr?.length) + ) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: 'Не заполнено поле', + path: ['selectObjectCategoryTax'], + }); + } + + if (evo_leasingobject_type?.evo_id === '11' && !insNSIB) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: 'Страхование НСИБ обязательно для мотоциклистов', + path: ['selectInsNSIB'], + }); + } + } + + if (objectRegistration === 100_000_001 && !(vehicleTaxInYear > 0)) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: 'Значение должно быть больше 0', + path: ['tbxVehicleTaxInYear'], + }); + } + + if (objectRegistration === 100_000_001 && !typePTS) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: 'Не заполнено поле', + path: ['radioTypePTS'], + }); + } + } + ); +}