Валидация данных юридического лица — здесь набор методов для валидации ИНН, КПП, ОГРН(ИП), ОКПО… в реализации для typescript.
Видео 1, — простая валидация формы регистрации с подтверждение пароля.
Видео 2 — валидация файлов, изменения схемы валидации в зависимости от данных полей формы.
Генератор тестовых данных юр. лица
Нужно запомнить, что в typescipt первым аргументом метода будет this. Тип у this будет такой же как у ассоциированной с ним схемы.
// В данном методе this - это StringShema function checkPayment(this: yup.StringSchema, ref: any, msg: string) { return this.test({ name: 'checkPaymentMethod', exclusive: false, message: msg || 'accountNumber', params: { reference: ref.path}, test: function(value: string){ return checkPaymetAccount(value, this.resolve(ref)) } }) }
Добавление метода будет принимать тип схемы нашего нового метода:
yup.addMethod<yup.StringSchema>(yup.string, 'checkPaymentMethod', checkPayment);
А перед всем этим мы должны задекларировать модуль, добавив типы методов соответствующих интерфейсов:
declare module "yup" { interface StringSchema { checkPaymentMethod(ref: Ref): StringSchema; checkCorrespondentMethod(ref: Ref): StringSchema; }, interface NumberSchema { ... }, ...... }
App.js
import React from 'react'; import { Formik } from 'formik' import yup, { checkBIK, isINNLegalEntity } from './validation' import './App.scss' function App() { const getError = (touched, error) => { return touched && error && <p key={error} className={'error'}>{error}</p> } const validationsSchema = yup.object().shape({ bik: yup.string().test('BIK', 'БИК не валидный', checkBIK), accountNumber: yup.string().checkPaymentMethod(yup.ref('bik'), 'Сообщение'), inn: yup.string().test('INN', 'ИНН не валидный', isINNLegalEntity) }) return ( <div> <Formik initialValues={{ bik: '', accountNumber: '', inn: '' }} validateOnBlur onSubmit={(values) => { console.log(values) }} validationSchema={validationsSchema} > {({ values, errors, touched, handleChange, handleBlur, isValid, handleSubmit, dirty }) => ( <div className={`from`}> <p> <label htmlFor={`bik`}>БИК</label><br /> <input className={'input'} type={`text`} name={`bik`} onChange={handleChange} onBlur={handleBlur} value={values.bik} /> </p> {getError(touched.bik, errors.bik)} <p> <label htmlFor={`accountNumber`}>Р/C</label><br /> <input className={'input'} type={`text`} name={`accountNumber`} onChange={handleChange} onBlur={handleBlur} value={values.accountNumber} /> </p> {getError(touched.accountNumber, errors.accountNumber)} <p> <label htmlFor={`inn`}>ИНН</label><br /> <input className={'input'} type={`text`} name={`inn`} onChange={handleChange} onBlur={handleBlur} value={values.inn} /> </p> {getError(touched.inn, errors.inn)} <button disabled={!isValid || !dirty} onClick={handleSubmit} type={`submit`} >Отправить</button> </div> )} </Formik> </div> ); } export default App; // Р / с 40702810038050103285 // К / с 30101810400000000225 // БИК 044525225
validation.js
import * as yup from 'yup' export const checkBIK = (value) => { if (!/^\d{9}$/.test(value)) return false const thirdPart = value.slice(-3); if (+thirdPart === 0 || +thirdPart === 1 || +thirdPart === 2) return true return +thirdPart >= 50 && +thirdPart < 1000 } export const checkPaymetAccount = (value, bik) => { const valueToString = value ? value.toString() : ''; if (checkBIK(bik)) { if (!/[^0-9]/.test(valueToString) && valueToString.length === 20) { const bikRs = bik.toString().slice(-3) + valueToString; let checkSum = 0; const coefficients = [7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1]; for (var i in coefficients) { checkSum += coefficients[i] * (Number(bikRs[i]) % 10); } return checkSum % 10 === 0; } } return false; }; export const isINNLegalEntity = (value) => { const valueToString = value ? value.toString() : '' const getN = (index) => (parseInt(valueToString[index])) if (valueToString.length === 10) { const dgt10 = (( 2 * getN(0) + 4 * getN(1) + 10 * getN(2) + 3 * getN(3) + 5 * getN(4) + 9 * getN(5) + 4 * getN(6) + 6 * getN(7) + 8 * getN(8) ) % 11) % 10 return (getN(9) === dgt10) } return false } function checkPayment(ref, msg) { return this.test({ name: 'checkPaymentMethod', exclusive: false, message: msg || 'accountNumber not valid', // Сообщение об ошибке params: { reference: ref ? ref.path : undefined }, test: function (value) { return checkPaymetAccount(value, this.resolve(ref)) // Функция валидации } }) } yup.addMethod(yup.string, 'checkPaymentMethod', checkPayment) export default yup