diff --git a/apps/web/config/process/default.ts b/apps/web/config/process/default.ts index 8ea6f8f..0eb5236 100644 --- a/apps/web/config/process/default.ts +++ b/apps/web/config/process/default.ts @@ -16,7 +16,7 @@ import * as payments from '@/process/payments'; import * as subsidy from '@/process/subsidy'; import * as subsidyImportProgram from '@/process/subsidy-import-program'; // import * as supplierAgent from '@/process/supplier-agent'; -// import * as usedPl from '@/process/used-pl'; +import * as usedPl from '@/process/used-pl'; export default function useReactions() { useProcess(leadOpportunity); @@ -31,7 +31,7 @@ export default function useReactions() { useProcess(configurator); useProcess(createKP); useProcess(bonuses); - // useProcess(usedPl); + useProcess(usedPl); useProcess(subsidyImportProgram); useProcess(payments); useProcess(gibdd); diff --git a/apps/web/process/used-pl/reactions.ts b/apps/web/process/used-pl/reactions.ts index 50c88da..b7e63b7 100644 --- a/apps/web/process/used-pl/reactions.ts +++ b/apps/web/process/used-pl/reactions.ts @@ -1,8 +1,11 @@ /* eslint-disable @typescript-eslint/naming-convention */ import type { ProcessContext } from '../types'; +import { createValidationSchema } from './validation'; +import type { Elements } from '@/Components/Calculation/config/map/values'; import * as CRMTypes from '@/graphql/crm.types'; import ValidationHelper from '@/stores/validation/helper'; import { reaction } from 'mobx'; +import { uid } from 'radash'; export function common({ store, apolloClient }: ProcessContext) { const { $calculation } = store; @@ -150,41 +153,6 @@ export function common({ store, apolloClient }: ProcessContext) { } ); - /** - * Добавить реакцию на изменение Типа ПЛ selectLeaseObjectType , ПЛ БУ cbxLeaseObjectUsed и Моточасы tbxEngineHours: - * Если ПЛ БУ cbxLeaseObjectUsed = True и Тип ПЛ selectLeaseObjectType = Спецтехника (id=9) и Моточасы = 0, - * то поле Моточасы tbxEngineHours должно обводиться красной рамкой и выводиться сообщение - * "Укажите Моточасы, иначе красная рамка снимается. - * При красной рамке в данном поле нельзя осуществить расчет графика. - */ - { - const validationHelper = new ValidationHelper(); - - reaction( - () => $calculation.$values.getValues(['leaseObjectUsed', 'engineHours', 'leaseObjectType']), - async ({ leaseObjectType: leaseObjectTypeId, leaseObjectUsed, engineHours }) => { - if (!leaseObjectTypeId) { - validationHelper.removeErrors(); - - return; - } - - const { - data: { evo_leasingobject_type }, - } = await apolloClient.query({ - query: CRMTypes.GetLeaseObjectTypeDocument, - variables: { leaseObjectTypeId }, - }); - - $calculation.element('tbxEngineHours').validate({ - helper: validationHelper, - invalid: leaseObjectUsed && evo_leasingobject_type?.evo_id === '9' && !engineHours, - message: 'Не заполнено поле', - }); - } - ); - } - reaction( () => $calculation.element('cbxLeaseObjectUsed').getValue(), (leaseObjectUsed) => { @@ -196,16 +164,6 @@ export function common({ store, apolloClient }: ProcessContext) { } ); - reaction( - () => $calculation.$values.getValues(['mileage', 'leaseObjectUsed']), - ({ mileage, leaseObjectUsed }) => { - $calculation.element('tbxMileage').validate({ - invalid: leaseObjectUsed && !mileage, - message: 'Не заполнено поле', - }); - } - ); - reaction( () => $calculation.element('cbxLeaseObjectUsed').getValue(), (leaseObjectUsed) => { @@ -273,38 +231,6 @@ export function common({ store, apolloClient }: ProcessContext) { } ); - /** - * Если "Категория" содержит данные, то должны быть доступными для набора только арабские цифры и буквы латинского алфавита за исключением I, O, Q, так как они сходны по начертанию с цифрами 1, 0, 9. Можно использовать регулярное выражение: "^[A-HJ-NPR-Za-hj-npr-z0-9]{17}$". - * Иначе (если Категория = пусто) то требуется аналогичная первому условию маска, но без проверки 17ти символов (допускать и больше и меньше символов, мб так: "^[A-HJ-NPR-Za-hj-npr-z0-9]{99}$". - * Вот так: /^[A-HJ-NPR-Za-hj-npr-z0-9]+$/ - */ - { - const vinRegex = /^[\dA-HJ-NPR-Za-hj-npr-z]+$/u; - const validationHelper = new ValidationHelper(); - - reaction( - () => $calculation.$values.getValues(['vin', 'leaseObjectCategory', 'leaseObjectUsed']), - ({ vin, leaseObjectCategory }) => { - if (!vin) { - validationHelper.removeErrors(); - - return; - } - - let invalid = vinRegex.test(vin) === false; - if (leaseObjectCategory && vin?.length !== 17) { - invalid = true; - } - - $calculation.element('tbxVIN').validate({ - helper: validationHelper, - invalid, - message: 'Неверно заполнено поле', - }); - } - ); - } - reaction( () => $calculation.element('cbxLeaseObjectUsed').getValue(), (leaseObjectUsed) => { @@ -316,3 +242,37 @@ export function common({ store, apolloClient }: ProcessContext) { } ); } + +const key = uid(7); + +export function validation(context: ProcessContext) { + const { store } = context; + const { $calculation } = store; + const validationSchema = createValidationSchema(context); + + const helper = new ValidationHelper(); + reaction( + () => + $calculation.$values.getValues([ + 'engineHours', + 'leaseObjectCategory', + 'leaseObjectType', + 'leaseObjectUsed', + 'mileage', + 'vin', + ]), + async (values) => { + helper.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) helper.add(removeError); + }); + }); + } + } + ); +} diff --git a/apps/web/process/used-pl/validation.ts b/apps/web/process/used-pl/validation.ts new file mode 100644 index 0000000..b759cbd --- /dev/null +++ b/apps/web/process/used-pl/validation.ts @@ -0,0 +1,81 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import type { ValidationContext } from '../types'; +import ValuesSchema from '@/config/schema/values'; +import * as CRMTypes from '@/graphql/crm.types'; +import { z } from 'zod'; + +const vinRegex = /^[\dA-HJ-NPR-Za-hj-npr-z]+$/u; + +export function createValidationSchema({ apolloClient }: ValidationContext) { + return ValuesSchema.pick({ + engineHours: true, + leaseObjectCategory: true, + leaseObjectType: true, + leaseObjectUsed: true, + mileage: true, + vin: true, + }).superRefine( + async ( + { + engineHours, + leaseObjectCategory, + leaseObjectType: leaseObjectTypeId, + leaseObjectUsed, + mileage, + vin, + }, + ctx + ) => { + /** + * Добавить реакцию на изменение Типа ПЛ selectLeaseObjectType , ПЛ БУ cbxLeaseObjectUsed и Моточасы tbxEngineHours: + * Если ПЛ БУ cbxLeaseObjectUsed = True и Тип ПЛ selectLeaseObjectType = Спецтехника (id=9) и Моточасы = 0, + * то поле Моточасы tbxEngineHours должно обводиться красной рамкой и выводиться сообщение + * "Укажите Моточасы, иначе красная рамка снимается. + * При красной рамке в данном поле нельзя осуществить расчет графика. + */ + if (leaseObjectTypeId) { + const { + data: { evo_leasingobject_type }, + } = await apolloClient.query({ + query: CRMTypes.GetLeaseObjectTypeDocument, + variables: { leaseObjectTypeId }, + }); + if (leaseObjectUsed && evo_leasingobject_type?.evo_id === '9' && !engineHours) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: 'Не заполнено поле', + path: ['tbxEngineHours'], + }); + } + } + + if (leaseObjectUsed && !mileage) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: 'Не заполнено поле', + path: ['tbxMileage'], + }); + } + + /** + * Если "Категория" содержит данные, то должны быть доступными для набора только арабские цифры и буквы латинского алфавита за исключением I, O, Q, так как они сходны по начертанию с цифрами 1, 0, 9. Можно использовать регулярное выражение: "^[A-HJ-NPR-Za-hj-npr-z0-9]{17}$". + * Иначе (если Категория = пусто) то требуется аналогичная первому условию маска, но без проверки 17ти символов (допускать и больше и меньше символов, мб так: "^[A-HJ-NPR-Za-hj-npr-z0-9]{99}$". + * Вот так: /^[A-HJ-NPR-Za-hj-npr-z0-9]+$/ + */ + if (vin) { + let invalid = vinRegex.test(vin) === false; + if (leaseObjectCategory && vin?.length !== 17) { + invalid = true; + } + + if (invalid) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: 'Неверно заполнено поле', + path: ['tbxVIN'], + }); + } + } + } + ); +}