From 14007de20810ea64ec8edb565e01b64f990439be Mon Sep 17 00:00:00 2001 From: Chika Date: Thu, 19 May 2022 18:08:02 +0300 Subject: [PATCH] Components: add configs for Calculation Elements --- .eslintrc.json | 3 +- .../Calculation/config/elements-builders.ts | 42 ++ .../Calculation/config/elements-components.ts | 173 ++++++++ .../Calculation/config/elements-props.ts | 406 ++++++++++++++++++ .../Calculation/config/elements-titles.ts | 156 +++++++ Components/Calculation/config/map-actions.ts | 9 +- Components/Calculation/config/map-computed.ts | 8 +- Components/Calculation/config/map-values.ts | 2 +- .../Calculation/types/elements-props.ts | 165 +++++++ Components/Spinner.jsx | 14 - Elements/Button.tsx | 10 +- Elements/Checkbox.tsx | 15 +- Elements/InputNumber.tsx | 4 +- Elements/Link.tsx | 16 +- Elements/Radio.tsx | 4 +- Elements/icons/DownloadOutlined.jsx | 3 + constants/values.js | 3 + package.json | 1 + tools/date.js | 6 + tools/format.js | 10 + tools/function.js | 5 + tools/number.ts | 4 + yarn.lock | 5 + 23 files changed, 1030 insertions(+), 34 deletions(-) create mode 100644 Components/Calculation/config/elements-builders.ts create mode 100644 Components/Calculation/config/elements-components.ts create mode 100644 Components/Calculation/config/elements-props.ts create mode 100644 Components/Calculation/config/elements-titles.ts create mode 100644 Components/Calculation/types/elements-props.ts delete mode 100644 Components/Spinner.jsx create mode 100644 Elements/icons/DownloadOutlined.jsx create mode 100644 constants/values.js create mode 100644 tools/date.js create mode 100644 tools/format.js create mode 100644 tools/function.js create mode 100644 tools/number.ts diff --git a/.eslintrc.json b/.eslintrc.json index 7d8d609..6f44ae8 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -47,6 +47,7 @@ "allowBind": false } ], - "newline-before-return": "warn" + "newline-before-return": "warn", + "@typescript-eslint/consistent-type-imports": "error" } } diff --git a/Components/Calculation/config/elements-builders.ts b/Components/Calculation/config/elements-builders.ts new file mode 100644 index 0000000..6ed85d6 --- /dev/null +++ b/Components/Calculation/config/elements-builders.ts @@ -0,0 +1,42 @@ +import buildAction from '../builders/build-action'; +import buildComputed from '../builders/build-computed'; +import buildReadonly from '../builders/build-readonly'; +import buildValue from '../builders/build-value'; +import components from './elements-components'; + +export const defaultBuilders = Object.keys(components).reduce((acc, elementName) => { + acc[elementName] = buildValue; + + return acc; + // eslint-disable-next-line object-curly-newline +}, {} as Record); + +export const overrideBuilders: Partial> = { + labelLeaseObjectRisk: buildComputed, + tbxInsKaskoPriceLeasePeriod: buildComputed, + labelIrrInfo: buildComputed, + labelRegistrationDescription: buildComputed, + btnCreateKP: buildAction, + btnCalculate: buildAction, + + labelResultTotalGraphwithNDS: buildReadonly, + labelResultPlPrice: buildReadonly, + labelResultPriceUpPr: buildReadonly, + labelResultIRRGraphPerc: buildReadonly, + labelResultIRRNominalPerc: buildReadonly, + labelResultInsKasko: buildReadonly, + labelResultInsOsago: buildReadonly, + labelResultDopProdSum: buildReadonly, + labelResultFirstPayment: buildReadonly, + labelResultLastPayment: buildReadonly, + labelResultTerm: buildReadonly, + labelResultAB_FL: buildReadonly, + labelResultAB_UL: buildReadonly, + labelResultBonusMPL: buildReadonly, + labelResultDopMPLLeasing: buildReadonly, + labelResultBonusDopProd: buildReadonly, + labelResultBonusSafeFinance: buildReadonly, + labelResultFirstPaymentRiskPolicy: buildReadonly, +}; + +export default Object.assign(defaultBuilders, overrideBuilders); diff --git a/Components/Calculation/config/elements-components.ts b/Components/Calculation/config/elements-components.ts new file mode 100644 index 0000000..77fdffa --- /dev/null +++ b/Components/Calculation/config/elements-components.ts @@ -0,0 +1,173 @@ +import Button from 'Elements/Button'; +import Checkbox from 'Elements/Checkbox'; +import Input from 'Elements/Input'; +import InputNumber from 'Elements/InputNumber'; +import Link from 'Elements/Link'; +import Radio from 'Elements/Radio'; +import Select from 'Elements/Select'; +import Switch from 'Elements/Switch'; +import Text from 'Elements/Text'; +import type { Elements as ActionElements } from './map-actions'; +import type { Elements as ComputedElements } from './map-computed'; +import type { Elements } from './map-values'; + +const components: Record< + Elements | ComputedElements | ActionElements, + (props: any) => JSX.Element +> = { + selectProduct: Select, + selectClientRisk: Select, + selectClientType: Select, + selectSupplierCurrency: Select, + tbxLeaseObjectPrice: InputNumber, + tbxLeaseObjectPriceWthtVAT: InputNumber, + tbxVATInLeaseObjectPrice: InputNumber, + tbxSupplierDiscountRub: InputNumber, + tbxSupplierDiscountPerc: InputNumber, + radioBalanceHolder: Radio, + tbxSaleBonus: InputNumber, + tbxFirstPaymentPerc: InputNumber, + tbxFirstPaymentRub: InputNumber, + radioLastPaymentRule: Radio, + tbxLastPaymentPerc: InputNumber, + tbxLastPaymentRub: InputNumber, + tbxRedemptionPaymentSum: InputNumber, + tbxLeasingPeriod: InputNumber, + radioGraphType: Radio, + tbxParmentsDecreasePercent: InputNumber, + selectSeasonType: Select, + selectHighSeasonStart: Select, + tbxComissionPerc: InputNumber, + tbxComissionRub: InputNumber, + selectLeaseObjectType: Select, + selectBrand: Select, + selectModel: Select, + selectConfiguration: Select, + labelDepreciationGroup: Text, + cbxLeaseObjectUsed: Checkbox, + radioDeliveryTime: Radio, + tbxLeaseObjectCount: InputNumber, + selectLeaseObjectUseFor: Select, + tbxLeaseObjectYear: InputNumber, + selectLeaseObjectCategory: Select, + selectEngineType: Select, + tbxLeaseObjectMotorPower: InputNumber, + tbxEngineVolume: InputNumber, + tbxMaxMass: InputNumber, + tbxCountSeats: InputNumber, + tbxMaxSpeed: InputNumber, + cbxWithTrailer: Checkbox, + selectDealer: Select, + selectDealerPerson: Select, + selectDealerRewardCondition: Select, + tbxDealerRewardSumm: InputNumber, + selectDealerBroker: Select, + selectDealerBrokerRewardCondition: Select, + tbxDealerBrokerRewardSumm: InputNumber, + selectIndAgent: Select, + selectIndAgentRewardCondition: Select, + tbxIndAgentRewardSumm: InputNumber, + selectCalcDoubleAgent: Select, + selectCalcDoubleAgentRewardCondition: Select, + tbxCalcDoubleAgentRewardSumm: InputNumber, + selectCalcBroker: Select, + selectCalcBrokerRewardCondition: Select, + tbxCalcBrokerRewardSum: InputNumber, + selectCalcFinDepartment: Select, + selectFinDepartmentRewardCondtion: Select, + tbxFinDepartmentRewardSumm: InputNumber, + cbxInsDecentral: Switch, + radioInsKaskoType: Radio, + tbxInsFranchise: InputNumber, + cbxInsUnlimitDrivers: Switch, + tbxInsAgeDrivers: InputNumber, + tbxInsExpDrivers: InputNumber, + tbxINNForCalc: InputNumber, + selectGPSBrand: Select, + selectGPSModel: Select, + selectRegionRegistration: Select, + selectTownRegistration: Select, + radioInfuranceOPF: Radio, + selectRegistration: Select, + selectInsNSIB: Select, + radioRequirementTelematic: Radio, + selectTracker: Select, + selectTelematic: Select, + selectTechnicalCard: Select, + cbxLastPaymentRedemption: Switch, + cbxPriceWithDiscount: Switch, + cbxFullPriceWithDiscount: Switch, + cbxCostIncrease: Switch, + cbxInsurance: Switch, + cbxRegistrationQuote: Switch, + cbxTechnicalCardQuote: Switch, + cbxNSIB: Switch, + cbxQuoteRedemptionGraph: Switch, + cbxShowFinGAP: Switch, + tbxQuoteName: Input, + radioQuoteContactGender: Radio, + cbxDisableChecks: Switch, + selectTarif: Select, + tbxCreditRate: InputNumber, + selectRate: Select, + tbxMaxPriceChange: InputNumber, + tbxImporterRewardPerc: InputNumber, + tbxImporterRewardRub: InputNumber, + selectLead: Select, + selectOpportunity: Select, + selectQuote: Select, + cbxRecalcWithRevision: Checkbox, + tbxIRR_Perc: InputNumber, + tbxMileage: InputNumber, + tbxEngineHours: InputNumber, + radioCalcType: Radio, + tbxTotalPayments: InputNumber, + radioObjectRegistration: Radio, + selectObjectRegionRegistration: Select, + tbxVehicleTaxInYear: InputNumber, + tbxVehicleTaxInLeasingPeriod: InputNumber, + selectObjectCategoryTax: Select, + selectObjectTypeTax: Select, + radioTypePTS: Radio, + selectLegalClientRegion: Select, + selectLegalClientTown: Select, + selectSubsidy: Select, + selectFuelCard: Select, + labelSubsidySum: Text, + tbxMinPriceChange: InputNumber, + + /** Computed Elements */ + labelLeaseObjectRisk: Text, + tbxInsKaskoPriceLeasePeriod: InputNumber, + labelIrrInfo: Text, + labelRegistrationDescription: Text, + + /** Result Elements */ + labelResultTotalGraphwithNDS: Text, + labelResultPlPrice: Text, + labelResultPriceUpPr: Text, + labelResultIRRGraphPerc: Text, + labelResultIRRNominalPerc: Text, + labelResultInsKasko: Text, + labelResultInsOsago: Text, + labelResultDopProdSum: Text, + labelResultFirstPayment: Text, + labelResultLastPayment: Text, + labelResultTerm: Text, + labelResultAB_FL: Text, + labelResultAB_UL: Text, + labelResultBonusMPL: Text, + labelResultDopMPLLeasing: Text, + labelResultBonusDopProd: Text, + labelResultBonusSafeFinance: Text, + labelResultFirstPaymentRiskPolicy: Text, + + /** Button Elements */ + btnCreateKP: Button, + btnCalculate: Button, + + /** Link Elements */ + linkDownloadKp: Link, +}; + +export default components; diff --git a/Components/Calculation/config/elements-props.ts b/Components/Calculation/config/elements-props.ts new file mode 100644 index 0000000..f292187 --- /dev/null +++ b/Components/Calculation/config/elements-props.ts @@ -0,0 +1,406 @@ +import { MAX_FRANCHISE } from 'constants/values'; +import DownloadOutlined from 'Elements/icons/DownloadOutlined'; +import date from 'tools/date'; +import { formatMoney, formatNumber } from 'tools/format'; +import { pipe } from 'tools/function'; +import { round } from 'tools/number'; +import type { ElementsProps } from '../types/elements-props'; + +const props: Partial = { + tbxLeaseObjectPrice: { + min: 0.0, + max: 1000000000.0, + step: 10000.0, + precision: 2, + formatter: formatNumber, + }, + tbxLeaseObjectPriceWthtVAT: { + min: 0.0, + max: 1000000000.0, + step: 10000.0, + precision: 2, + formatter: formatNumber, + }, + tbxVATInLeaseObjectPrice: { + min: 0.0, + max: 1000000000.0, + step: 10000.0, + precision: 2, + formatter: formatNumber, + }, + tbxEngineHours: { + min: 0.0, + step: 10.0, + precision: 2, + formatter: formatNumber, + }, + tbxSupplierDiscountRub: { + min: 0, + max: 1000000000, + step: 10000.0, + precision: 2, + formatter: formatNumber, + }, + tbxSupplierDiscountPerc: { + min: 0, + max: 100, + precision: 2, + formatter: formatNumber, + }, + radioBalanceHolder: { + optionType: 'button', + buttonStyle: 'solid', + }, + tbxSaleBonus: { + min: 0.0, + // max: 1.30, + step: 0.1, + precision: 2, + formatter: formatNumber, + }, + tbxFirstPaymentPerc: { + min: 0, + max: 50, + precision: 4, + formatter: formatNumber, + }, + tbxFirstPaymentRub: { + min: 0, + max: 1000000000, + step: 10000.0, + precision: 2, + formatter: formatNumber, + }, + tbxLastPaymentPerc: { + min: 0, + max: 70, + step: 1.0, + precision: 6, + formatter: formatNumber, + }, + tbxLastPaymentRub: { + min: 0, + max: 1000000000, + step: 10000.0, + precision: 2, + formatter: formatNumber, + }, + tbxRedemptionPaymentSum: { + min: 1000, + max: 2000, + step: 1000.0, + precision: 2, + formatter: formatNumber, + }, + tbxLeasingPeriod: { + min: 13, + max: 60, + }, + tbxParmentsDecreasePercent: { + min: 50, + max: 99, + }, + tbxComissionPerc: { + min: 0, + max: 100, + }, + tbxComissionRub: { + min: 0, + max: 1000000000, + step: 10000.0, + }, + selectLeaseObjectType: { + showSearch: true, + }, + selectBrand: { + showSearch: true, + }, + selectModel: { + showSearch: true, + }, + selectConfiguration: { + showSearch: true, + }, + radioDeliveryTime: { + optionType: 'button', + buttonStyle: 'solid', + }, + tbxLeaseObjectCount: { + min: 1, + max: 1000, + }, + selectLeaseObjectUseFor: { + showSearch: true, + }, + tbxLeaseObjectYear: { + min: 1994, + max: date().year(), + }, + selectLeaseObjectCategory: { + showSearch: false, + }, + selectEngineType: { + showSearch: true, + }, + tbxLeaseObjectMotorPower: { + min: 0.0, + max: 20000.0, + step: 10.0, + precision: 2, + formatter: formatNumber, + }, + tbxEngineVolume: { + min: 0.0, + max: 99.9999, + step: 0.5, + precision: 4, + formatter: formatNumber, + }, + tbxMaxMass: { + min: 0, + max: 999999, + step: 100, + formatter: formatNumber, + }, + tbxCountSeats: { + min: 0, + max: 2000, + }, + tbxMaxSpeed: { + min: 0, + max: 2000, + }, + selectDealer: { + showSearch: true, + }, + tbxDealerRewardSumm: { + min: 0.0, + max: 20.0, + step: 0.1, + precision: 2, + formatter: formatNumber, + }, + tbxDealerBrokerRewardSumm: { + min: 0.0, + max: 20.0, + step: 0.1, + precision: 2, + formatter: formatNumber, + }, + tbxIndAgentRewardSumm: { + min: 0.0, + max: 20.0, + step: 0.1, + precision: 2, + formatter: formatNumber, + }, + tbxCalcDoubleAgentRewardSumm: { + min: 0.0, + max: 20.0, + step: 0.1, + precision: 2, + formatter: formatNumber, + }, + tbxCalcBrokerRewardSum: { + min: 0.0, + max: 20.0, + step: 0.1, + precision: 2, + formatter: formatNumber, + }, + tbxFinDepartmentRewardSumm: { + min: 0.0, + max: 20.0, + step: 0.1, + precision: 2, + formatter: formatNumber, + }, + radioInsKaskoType: { + optionType: 'button', + buttonStyle: 'solid', + }, + tbxInsFranchise: { + min: 0, + max: MAX_FRANCHISE, + step: 10000.0, + precision: 2, + formatter: formatNumber, + }, + tbxInsAgeDrivers: { + // min: 18, + // max: 99, + }, + tbxInsExpDrivers: { + // min: 0, + // max: 99, + }, + selectRegionRegistration: { + showSearch: true, + }, + selectTownRegistration: { + showSearch: true, + }, + radioQuoteContactGender: { + optionType: 'button', + buttonStyle: 'solid', + }, + btnCreateKP: { + type: 'primary', + text: 'Создать КП', + }, + tbxCreditRate: { + min: 0.0, + max: 99.99, + step: 0.1, + }, + tbxMaxPriceChange: { + min: 0, + max: 34999990, + step: 10000.0, + }, + tbxMinPriceChange: { + min: 0, + max: 34999990, + step: 10000.0, + }, + tbxImporterRewardPerc: { + min: 0.0, + max: 99.99, + step: 0.1, + precision: 2, + }, + tbxImporterRewardRub: { + min: 0.0, + max: 1000000000.0, + step: 10000.0, + precision: 2, + }, + selectLead: { + showSearch: true, + }, + selectOpportunity: { + showSearch: true, + }, + selectQuote: { + showSearch: true, + }, + btnCalculate: { + text: 'Рассчитать график', + type: 'primary', + }, + tbxIRR_Perc: { + min: 0.0, + max: 500.0, + step: 0.0001, + precision: 6, + formatter: formatNumber, + }, + linkDownloadKp: { + type: 'primary', + text: 'Скачать КП', + icon: DownloadOutlined, + }, + tbxMileage: { + min: 0, + step: 100.0, + precision: 2, + formatter: formatNumber, + }, + cbxRecalcWithRevision: { + text: 'Пересчет без пересмотра', + style: { + marginBottom: '8px', + }, + }, + radioCalcType: { + optionType: 'button', + buttonStyle: 'solid', + }, + tbxTotalPayments: { + min: 0, + step: 1000, + precision: 2, + formatter: formatNumber, + }, + tbxVehicleTaxInYear: { + min: 0, + step: 100, + max: 9999999, + precision: 2, + }, + tbxVehicleTaxInLeasingPeriod: { + min: 0, + step: 100, + max: 9999999, + precision: 2, + }, + selectObjectRegionRegistration: { + showSearch: true, + }, + tbxInsKaskoPriceLeasePeriod: { + min: 0, + precision: 2, + formatter: formatNumber, + readOnly: true, + controls: false, + }, + selectLegalClientRegion: { + showSearch: true, + }, + selectLegalClientTown: { + showSearch: true, + }, + radioInfuranceOPF: { + optionType: 'button', + buttonStyle: 'solid', + }, +}; + +const moneyResultElementsProps = ( + [ + 'labelResultTotalGraphwithNDS', + 'labelResultPlPrice', + 'labelResultInsKasko', + 'labelResultInsOsago', + 'labelResultDopProdSum', + 'labelResultFirstPayment', + 'labelResultLastPayment', + 'labelResultAB_FL', + 'labelResultAB_UL', + 'labelResultBonusMPL', + 'labelResultDopMPLLeasing', + 'labelResultBonusDopProd', + 'labelSubsidySum', + 'labelResultBonusSafeFinance', + ] as (keyof ElementsProps)[] +).reduce( + (ac, a) => ({ + ...ac, + [a]: { + middleware: (value: number) => pipe(round, formatMoney)(value), + }, + }), + // eslint-disable-next-line object-curly-newline + {} +); + +const numberResultElementsProps = ( + [ + 'labelResultPriceUpPr', + 'labelResultIRRGraphPerc', + 'labelResultIRRNominalPerc', + 'labelResultTerm', + 'labelResultFirstPaymentRiskPolicy', + ] as (keyof ElementsProps)[] +).reduce( + (ac, a) => ({ + ...ac, + [a]: { + middleware: (value: number) => pipe(round)(value), + }, + }), + // eslint-disable-next-line object-curly-newline + {} +); + +export default Object.assign(props, moneyResultElementsProps, numberResultElementsProps); diff --git a/Components/Calculation/config/elements-titles.ts b/Components/Calculation/config/elements-titles.ts new file mode 100644 index 0000000..86f6d8b --- /dev/null +++ b/Components/Calculation/config/elements-titles.ts @@ -0,0 +1,156 @@ +import type { Elements as ComputedElements } from './map-computed'; +import type { Elements } from './map-values'; + +const titles: Record = { + selectLead: 'Интерес', + selectOpportunity: 'Лизинговая сделка', + selectQuote: 'Предложение', + selectProduct: 'Продукт', + cbxRecalcWithRevision: 'Пересчёт без пересмотра', + selectClientRisk: 'Риск клиента', + selectClientType: 'Тип клиента', + tbxLeaseObjectPrice: 'Стоимость ПЛ с НДС', + selectSupplierCurrency: 'Валюта поставщика', + tbxSupplierDiscountRub: 'Скидка от поставщика', + tbxSupplierDiscountPerc: 'Скидка от поставщика, %', + tbxLeasingPeriod: 'Срок лизинга, мес', + tbxFirstPaymentPerc: 'Первый платеж, %', + tbxFirstPaymentRub: 'Первый платеж, руб.', + tbxLastPaymentPerc: 'Последний платеж, %', + tbxLastPaymentRub: 'Последний платеж, руб.', + radioLastPaymentRule: 'Последний платеж', + tbxRedemptionPaymentSum: 'Сумма выкупного платежа, руб', + radioBalanceHolder: 'Балансодержатель', + radioGraphType: 'Вид графика', + tbxParmentsDecreasePercent: 'Процент убывания платежей', + selectSeasonType: 'Тип дегрессии/сезонности', + selectHighSeasonStart: 'Смещение сезонности', + tbxComissionPerc: 'Комиссия, %', + tbxComissionRub: 'Комиссия, руб.', + tbxSaleBonus: 'Размер бонуса МПЛ', + tbxIRR_Perc: 'IRR, %', + selectLeaseObjectType: 'Тип предмета лизинга', + radioDeliveryTime: 'Срок поставки', + labelDepreciationGroup: 'Группа обесценения', + tbxLeaseObjectCount: 'Кол-во ПЛ в расчете', + cbxWithTrailer: 'ТС с прицепом', + cbxLeaseObjectUsed: 'ПЛ БУ', + tbxMaxMass: 'Разрешенная макс.масса(кг)', + tbxCountSeats: 'Количество мест', + tbxMaxSpeed: 'Макс. конструктивная скорость (при ПСМ)', + selectBrand: 'Марка', + selectModel: 'Модель', + selectConfiguration: 'Комплектация', + tbxLeaseObjectYear: 'Год выпуска', + selectEngineType: 'Тип двигателя', + selectLeaseObjectCategory: 'Категория ТС', + tbxLeaseObjectMotorPower: 'Мощность, л.с.', + tbxEngineVolume: 'Объем двигателя, л', + selectLeaseObjectUseFor: 'ПЛ используется для', + selectDealer: 'Салон приобретения', + selectDealerPerson: 'ЮЛ поставщика', + selectDealerRewardCondition: 'Условие АВ ЮЛ поставщика', + tbxDealerRewardSumm: 'Размер АВ ЮЛ поставщика', + selectDealerBroker: 'Брокер поставщика', + selectDealerBrokerRewardCondition: 'Условие АВ брокера поставщика', + tbxDealerBrokerRewardSumm: 'Размер АВ брокера поставщика', + selectIndAgent: 'Агент ФЛ', + selectIndAgentRewardCondition: 'Условие АВ агента ФЛ', + tbxIndAgentRewardSumm: 'Размер АВ агента ФЛ', + selectCalcDoubleAgent: 'Двойной агент', + selectCalcDoubleAgentRewardCondition: 'Условия АВ двойного агента', + tbxCalcDoubleAgentRewardSumm: 'Размер АВ двойного агента', + selectCalcBroker: 'Брокер', + selectCalcBrokerRewardCondition: 'Условие АВ брокера', + tbxCalcBrokerRewardSum: 'Размер АВ брокера', + selectCalcFinDepartment: 'Финотдел', + selectFinDepartmentRewardCondtion: 'Условие АВ финотдела', + tbxFinDepartmentRewardSumm: 'Размер АВ финотдела', + selectGPSBrand: 'Марка GPS', + selectGPSModel: 'Модель GPS', + selectRegionRegistration: 'Регион регистрации', + selectTownRegistration: 'Город регистрации', + radioInfuranceOPF: 'ОПФ для расчета страховки', + radioInsKaskoType: 'Тип страхования КАСКО', + cbxInsDecentral: 'Децентрализованное страхование', + tbxInsFranchise: 'Франшиза', + cbxInsUnlimitDrivers: 'Неограниченное число водителей', + tbxInsAgeDrivers: 'Наименьший возраст водителей', + tbxInsExpDrivers: 'Наименьший стаж водителей', + cbxLastPaymentRedemption: 'Последний платеж считать выкупным', + cbxShowFinGAP: 'Отображать EVO-Safe Finance', + cbxPriceWithDiscount: 'Отображать стоимость ПЛ со скидкой', + cbxFullPriceWithDiscount: 'Отображать полную стоимость ПЛ (без скидки)', + cbxCostIncrease: 'Отображать удорожание', + cbxInsurance: 'Отображать страхование', + cbxRegistrationQuote: 'Отображать регистрацию', + cbxTechnicalCardQuote: 'Отображать карту техпомощи', + cbxNSIB: 'Отображать НСИБ', + tbxQuoteName: 'Имя', + radioQuoteContactGender: 'Пол', + cbxQuoteRedemptionGraph: 'Отображать график досрочного выкупа', + selectTarif: 'Тариф', + tbxCreditRate: 'Ставка привлечения, %', + selectRate: 'Ставка привлечения', + tbxMaxPriceChange: 'Макс.возможное изменение стоимости ПЛ', + tbxImporterRewardPerc: 'АВ импортера, %', + tbxImporterRewardRub: 'АВ импортера, руб.', + cbxDisableChecks: 'Отключить все проверки', + selectRegistration: 'Регистрация', + selectInsNSIB: 'НСИБ', + selectTechnicalCard: 'Карта техпомощи', + radioRequirementTelematic: 'Программа средства контроля', + selectTelematic: 'Телематика ', + selectTracker: 'Маяк', + tbxMileage: 'Пробег, км', + radioCalcType: 'Расчет от', + tbxTotalPayments: 'Сумма платежей', + radioObjectRegistration: 'На кого регистрируется ТС', + selectObjectRegionRegistration: 'Регион регистрации в ГИБДД', + tbxVehicleTaxInYear: 'Трансп. налог, в год', + tbxVehicleTaxInLeasingPeriod: 'Трансп. налог на срок ДЛ', + selectObjectCategoryTax: 'Кат. по ТР ТС 018/2011', + selectObjectTypeTax: 'Тип ТС для ТН', + radioTypePTS: 'Тип ПТС', + tbxINNForCalc: 'ИНН контрагента', + selectLegalClientRegion: 'Регион по юр.адресу клиента', + selectLegalClientTown: 'Город по юр.адресу клиента', + selectSubsidy: 'Субсидия', + labelSubsidySum: 'Сумма субсидии с НДС', + selectFuelCard: 'Топливная карта', + tbxMinPriceChange: 'Мин. возможное изменение стоимости ПЛ', + tbxEngineHours: 'Моточасы', + tbxLeaseObjectPriceWthtVAT: 'Стоимость ПЛ без НДС', + tbxVATInLeaseObjectPrice: 'НДС в стоимости ПЛ', + + /** Result Elements */ + labelResultTotalGraphwithNDS: 'Итого по графику, с НДС', + labelResultPlPrice: 'Стоимость ПЛ с НДС', + labelResultPriceUpPr: 'Удорожание, год', + labelResultIRRGraphPerc: 'IRR по графику клиента, %', + labelResultIRRNominalPerc: 'IRR (номинал), %', + labelResultInsKasko: 'КАСКО, НС, ДГО в графике', + labelResultInsOsago: 'ОСАГО в графике', + labelResultDopProdSum: 'Общая сумма доп.продуктов', + labelResultFirstPayment: 'Первый платеж.', + labelResultLastPayment: 'Последний платеж.', + labelResultTerm: 'Срок, мес.', + labelResultAB_FL: 'АВ ФЛ, без НДФЛ.', + labelResultAB_UL: 'АВ ЮЛ, с НДС.', + labelResultBonusMPL: 'Бонус МПЛ за лизинг, без НДФЛ', + labelResultDopMPLLeasing: 'Доп.бонус МПЛ за лизинг, без НДФЛ', + labelResultBonusDopProd: 'Бонус МПЛ за доп.продукты, без НДФЛ', + labelResultBonusSafeFinance: 'Бонус за Safe Finance без НДФЛ', + labelResultFirstPaymentRiskPolicy: 'Первый платеж по риск политике, %', + + /** Link Elements */ + linkDownloadKp: 'Скачать КП', + + /** Computed Elements */ + labelIrrInfo: 'Диапазон IRR (Номинал)', + labelLeaseObjectRisk: 'Риск ПЛ', + labelRegistrationDescription: 'Описание регистрации', + tbxInsKaskoPriceLeasePeriod: 'Стоимость страховки КАСКО на весь срок', +}; + +export default titles; diff --git a/Components/Calculation/config/map-actions.ts b/Components/Calculation/config/map-actions.ts index a2c59d8..777dbf1 100644 --- a/Components/Calculation/config/map-actions.ts +++ b/Components/Calculation/config/map-actions.ts @@ -1,11 +1,16 @@ -export const elementsToActions: Record = { +function wrapElementsMap>(arg: T) { + return arg; +} + +const elementsToActions = wrapElementsMap({ btnCalculate: 'calculate', btnCreateKP: 'create-kp', -}; +}); export type Elements = keyof typeof elementsToActions; export function getAction(elementName: Elements) { const actionName = elementsToActions[elementName]; + return actionName; } diff --git a/Components/Calculation/config/map-computed.ts b/Components/Calculation/config/map-computed.ts index 602e322..6b51730 100644 --- a/Components/Calculation/config/map-computed.ts +++ b/Components/Calculation/config/map-computed.ts @@ -1,11 +1,15 @@ import type { ComputedValues } from 'stores/calculation/values/computed'; -export const elementsToComputed: Record = { +function wrapElementsMap>(arg: T) { + return arg; +} + +const elementsToComputed = wrapElementsMap({ labelLeaseObjectRisk: 'leaseObjectRiskName', tbxInsKaskoPriceLeasePeriod: 'insKaskoPriceLeasePeriod', labelIrrInfo: 'irrInfo', labelRegistrationDescription: 'registrationDescription', -}; +}); export type Elements = keyof typeof elementsToComputed; diff --git a/Components/Calculation/config/map-values.ts b/Components/Calculation/config/map-values.ts index c912e39..34ca75a 100644 --- a/Components/Calculation/config/map-values.ts +++ b/Components/Calculation/config/map-values.ts @@ -4,7 +4,7 @@ function wrapElementsMap>(arg: T) { return arg; } -export const elementsToValues = wrapElementsMap({ +const elementsToValues = wrapElementsMap({ selectLead: 'lead', selectOpportunity: 'opportunity', selectQuote: 'quote', diff --git a/Components/Calculation/types/elements-props.ts b/Components/Calculation/types/elements-props.ts new file mode 100644 index 0000000..f3a8b30 --- /dev/null +++ b/Components/Calculation/types/elements-props.ts @@ -0,0 +1,165 @@ +import type { ButtonProps } from 'Elements/Button'; +import type { CheckboxProps } from 'Elements/Checkbox'; +import type { InputProps } from 'Elements/Input'; +import type { InputNumberProps } from 'Elements/InputNumber'; +import type { LinkProps } from 'Elements/Link'; +import type { RadioProps } from 'Elements/Radio'; +import type { SelectProps } from 'Elements/Select'; +import type { SwitchProps } from 'Elements/Switch'; +import type { TextProps } from 'Elements/Text'; + +export interface ElementsProps { + selectProduct: SelectProps; + selectClientRisk: SelectProps; + selectClientType: SelectProps; + selectSupplierCurrency: SelectProps; + tbxLeaseObjectPrice: InputNumberProps; + tbxLeaseObjectPriceWthtVAT: InputNumberProps; + tbxVATInLeaseObjectPrice: InputNumberProps; + tbxSupplierDiscountRub: InputNumberProps; + tbxSupplierDiscountPerc: InputNumberProps; + radioBalanceHolder: RadioProps; + tbxSaleBonus: InputNumberProps; + tbxFirstPaymentPerc: InputNumberProps; + tbxFirstPaymentRub: InputNumberProps; + radioLastPaymentRule: RadioProps; + tbxLastPaymentPerc: InputNumberProps; + tbxLastPaymentRub: InputNumberProps; + tbxRedemptionPaymentSum: InputNumberProps; + tbxLeasingPeriod: InputNumberProps; + radioGraphType: RadioProps; + tbxParmentsDecreasePercent: InputNumberProps; + selectSeasonType: SelectProps; + selectHighSeasonStart: SelectProps; + tbxComissionPerc: InputNumberProps; + tbxComissionRub: InputNumberProps; + selectLeaseObjectType: SelectProps; + selectBrand: SelectProps; + selectModel: SelectProps; + selectConfiguration: SelectProps; + labelDepreciationGroup: TextProps; + cbxLeaseObjectUsed: CheckboxProps; + radioDeliveryTime: RadioProps; + tbxLeaseObjectCount: InputNumberProps; + selectLeaseObjectUseFor: SelectProps; + tbxLeaseObjectYear: InputNumberProps; + selectLeaseObjectCategory: SelectProps; + selectEngineType: SelectProps; + tbxLeaseObjectMotorPower: InputNumberProps; + tbxEngineVolume: InputNumberProps; + tbxMaxMass: InputNumberProps; + tbxCountSeats: InputNumberProps; + tbxMaxSpeed: InputNumberProps; + cbxWithTrailer: CheckboxProps; + selectDealer: SelectProps; + selectDealerPerson: SelectProps; + selectDealerRewardCondition: SelectProps; + tbxDealerRewardSumm: InputNumberProps; + selectDealerBroker: SelectProps; + selectDealerBrokerRewardCondition: SelectProps; + tbxDealerBrokerRewardSumm: InputNumberProps; + selectIndAgent: SelectProps; + selectIndAgentRewardCondition: SelectProps; + tbxIndAgentRewardSumm: InputNumberProps; + selectCalcDoubleAgent: SelectProps; + selectCalcDoubleAgentRewardCondition: SelectProps; + tbxCalcDoubleAgentRewardSumm: InputNumberProps; + selectCalcBroker: SelectProps; + selectCalcBrokerRewardCondition: SelectProps; + tbxCalcBrokerRewardSum: InputNumberProps; + selectCalcFinDepartment: SelectProps; + selectFinDepartmentRewardCondtion: SelectProps; + tbxFinDepartmentRewardSumm: InputNumberProps; + cbxInsDecentral: SwitchProps; + radioInsKaskoType: RadioProps; + tbxInsFranchise: InputNumberProps; + cbxInsUnlimitDrivers: SwitchProps; + tbxInsAgeDrivers: InputNumberProps; + tbxInsExpDrivers: InputNumberProps; + tbxINNForCalc: InputNumberProps; + selectGPSBrand: SelectProps; + selectGPSModel: SelectProps; + selectRegionRegistration: SelectProps; + selectTownRegistration: SelectProps; + radioInfuranceOPF: RadioProps; + selectRegistration: SelectProps; + selectInsNSIB: SelectProps; + radioRequirementTelematic: RadioProps; + selectTracker: SelectProps; + selectTelematic: SelectProps; + selectTechnicalCard: SelectProps; + cbxLastPaymentRedemption: SwitchProps; + cbxPriceWithDiscount: SwitchProps; + cbxFullPriceWithDiscount: SwitchProps; + cbxCostIncrease: SwitchProps; + cbxInsurance: SwitchProps; + cbxRegistrationQuote: SwitchProps; + cbxTechnicalCardQuote: SwitchProps; + cbxNSIB: SwitchProps; + cbxQuoteRedemptionGraph: SwitchProps; + cbxShowFinGAP: SwitchProps; + tbxQuoteName: InputProps; + radioQuoteContactGender: RadioProps; + cbxDisableChecks: SwitchProps; + selectTarif: SelectProps; + tbxCreditRate: InputNumberProps; + selectRate: SelectProps; + tbxMaxPriceChange: InputNumberProps; + tbxImporterRewardPerc: InputNumberProps; + tbxImporterRewardRub: InputNumberProps; + selectLead: SelectProps; + selectOpportunity: SelectProps; + selectQuote: SelectProps; + cbxRecalcWithRevision: CheckboxProps; + tbxIRR_Perc: InputNumberProps; + tbxMileage: InputNumberProps; + tbxEngineHours: InputNumberProps; + radioCalcType: RadioProps; + tbxTotalPayments: InputNumberProps; + radioObjectRegistration: RadioProps; + selectObjectRegionRegistration: SelectProps; + tbxVehicleTaxInYear: InputNumberProps; + tbxVehicleTaxInLeasingPeriod: InputNumberProps; + selectObjectCategoryTax: SelectProps; + selectObjectTypeTax: SelectProps; + radioTypePTS: RadioProps; + selectLegalClientRegion: SelectProps; + selectLegalClientTown: SelectProps; + selectSubsidy: SelectProps; + selectFuelCard: SelectProps; + labelSubsidySum: TextProps; + tbxMinPriceChange: InputNumberProps; + + /** Computed Elements */ + labelLeaseObjectRisk: TextProps; + tbxInsKaskoPriceLeasePeriod: InputNumberProps; + labelIrrInfo: TextProps; + labelRegistrationDescription: TextProps; + + /** Result Elements */ + labelResultTotalGraphwithNDS: TextProps; + labelResultPlPrice: TextProps; + labelResultPriceUpPr: TextProps; + labelResultIRRGraphPerc: TextProps; + labelResultIRRNominalPerc: TextProps; + labelResultInsKasko: TextProps; + labelResultInsOsago: TextProps; + labelResultDopProdSum: TextProps; + labelResultFirstPayment: TextProps; + labelResultLastPayment: TextProps; + labelResultTerm: TextProps; + labelResultAB_FL: TextProps; + labelResultAB_UL: TextProps; + labelResultBonusMPL: TextProps; + labelResultDopMPLLeasing: TextProps; + labelResultBonusDopProd: TextProps; + labelResultBonusSafeFinance: TextProps; + labelResultFirstPaymentRiskPolicy: TextProps; + + /** Button Elements */ + btnCreateKP: ButtonProps; + btnCalculate: ButtonProps; + + /** Link Elements */ + linkDownloadKp: LinkProps; +} diff --git a/Components/Spinner.jsx b/Components/Spinner.jsx deleted file mode 100644 index b067c41..0000000 --- a/Components/Spinner.jsx +++ /dev/null @@ -1,14 +0,0 @@ -import LoadingOutlined from '@ant-design/icons/lib/icons/LoadingOutlined'; -import { Spin } from 'antd'; - -export default Spin; - -const loadingOutlined = ( - -); -export const Outlined = ; diff --git a/Elements/Button.tsx b/Elements/Button.tsx index 4aca367..ee25b55 100644 --- a/Elements/Button.tsx +++ b/Elements/Button.tsx @@ -1,10 +1,9 @@ -import type { ButtonProps } from 'antd'; import { Button as AntButton } from 'antd'; +import type { BaseButtonProps } from 'antd/lib/button/button'; import { throttle } from 'lodash'; -import type { Status } from './types'; +import type { BaseElementProps } from './types'; -type ElementProps = { - status: Status; +type ElementProps = BaseElementProps & { action: () => void; text: string; }; @@ -19,10 +18,13 @@ export default function Button({ status, action, text }: ElementProps) { disabled={status === 'Disabled'} loading={status === 'Loading'} onClick={throttledAction} + ghost > {text} ); } +type ButtonProps = BaseButtonProps & Pick; + export type { ButtonProps }; diff --git a/Elements/Checkbox.tsx b/Elements/Checkbox.tsx index e9026b4..0acff79 100644 --- a/Elements/Checkbox.tsx +++ b/Elements/Checkbox.tsx @@ -1,18 +1,23 @@ -import type { CheckboxProps } from 'antd'; +import type { CheckboxProps as AntCheckboxProps } from 'antd'; import { Checkbox as AntCheckbox, Form } from 'antd'; import type { CheckboxChangeEvent } from 'antd/lib/checkbox'; import type { BaseElementProps } from './types'; const { Item: FormItem } = Form; +type ElementProps = BaseElementProps & { + text: string; +}; + export default function Checkbox({ value, setValue, status, isValid, help, + text, ...props -}: BaseElementProps) { +}: ElementProps) { function handleChange(e: CheckboxChangeEvent) { setValue(e.target.checked); } @@ -24,9 +29,13 @@ export default function Checkbox({ onChange={handleChange} disabled={status === 'Disabled'} {...props} - /> + > + {text} + ); } +type CheckboxProps = AntCheckboxProps & Pick; + export type { CheckboxProps }; diff --git a/Elements/InputNumber.tsx b/Elements/InputNumber.tsx index a0c4169..cc1f2ce 100644 --- a/Elements/InputNumber.tsx +++ b/Elements/InputNumber.tsx @@ -1,4 +1,4 @@ -import type { InputNumberProps } from 'antd'; +import type { InputNumberProps as AntInputNumberProps } from 'antd'; import { Form, InputNumber as AntInputNumber } from 'antd'; import type { BaseElementProps } from './types'; @@ -23,4 +23,6 @@ export default function InputNumber({ ); } +type InputNumberProps = AntInputNumberProps; + export type { InputNumberProps }; diff --git a/Elements/Link.tsx b/Elements/Link.tsx index b44abf7..8acb1c7 100644 --- a/Elements/Link.tsx +++ b/Elements/Link.tsx @@ -1,9 +1,13 @@ import DownloadOutlined from '@ant-design/icons/lib/icons/DownloadOutlined'; -import type { ButtonProps } from 'antd'; import { Button as AntButton } from 'antd'; +import type { BaseButtonProps } from 'antd/lib/button/button'; import type { BaseElementProps } from './types'; -export default function Link({ value, setValue, status, ...props }: BaseElementProps) { +type ElementProps = BaseElementProps & { + text: string; +}; + +export default function Link({ value, status, text, ...props }: ElementProps) { return ( } {...props} - /> + > + {text} + ); } -export type { ButtonProps as LinkProps }; +type LinkProps = BaseButtonProps & Pick; + +export type { LinkProps }; diff --git a/Elements/Radio.tsx b/Elements/Radio.tsx index c78f71e..8a2ef29 100644 --- a/Elements/Radio.tsx +++ b/Elements/Radio.tsx @@ -1,4 +1,4 @@ -import type { RadioChangeEvent, RadioProps } from 'antd'; +import type { RadioChangeEvent, RadioGroupProps } from 'antd'; import { Form, Radio as AntRadio } from 'antd'; import type { BaseElementProps, BaseOption } from './types'; @@ -34,4 +34,4 @@ export default function Radio({ ); } -export type { RadioProps }; +export type { RadioGroupProps as RadioProps }; diff --git a/Elements/icons/DownloadOutlined.jsx b/Elements/icons/DownloadOutlined.jsx new file mode 100644 index 0000000..c61295b --- /dev/null +++ b/Elements/icons/DownloadOutlined.jsx @@ -0,0 +1,3 @@ +import DownloadOutlined from '@ant-design/icons/lib/icons/DownloadOutlined'; + +export default ; diff --git a/constants/values.js b/constants/values.js new file mode 100644 index 0000000..0c65e8f --- /dev/null +++ b/constants/values.js @@ -0,0 +1,3 @@ +export const MAX_FRANCHISE = 75000; +export const MAX_INSURANCE = 2500000; +export const MIN_INSURANCE = 3000; diff --git a/package.json b/package.json index b4bfb91..b61338b 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "@apollo/client": "^3.6.0", "antd": "^4.20.5", "axios": "^0.26.1", + "dayjs": "^1.11.2", "graphql": "14.0.2 - 14.2.0 || ^14.3.1 || ^15.0.0", "less": "^4.1.2", "less-loader": "^10.2.0", diff --git a/tools/date.js b/tools/date.js new file mode 100644 index 0000000..b8bb00f --- /dev/null +++ b/tools/date.js @@ -0,0 +1,6 @@ +import dayjs from 'dayjs'; +import utc from 'dayjs/plugin/utc'; + +dayjs.extend(utc); + +export default dayjs; diff --git a/tools/format.js b/tools/format.js new file mode 100644 index 0000000..4304bbc --- /dev/null +++ b/tools/format.js @@ -0,0 +1,10 @@ +export function formatMoney(n = 0.0, currency = 'RUB') { + return Intl.NumberFormat('ru', { + style: 'currency', + currency, + }).format(n); +} + +export function formatNumber(n = 0.0) { + return Intl.NumberFormat('ru').format(n); +} diff --git a/tools/function.js b/tools/function.js new file mode 100644 index 0000000..983855b --- /dev/null +++ b/tools/function.js @@ -0,0 +1,5 @@ +/* eslint-disable import/prefer-default-export */ + +export function pipe(...fns) { + return (x) => fns.reduce((v, f) => f(v), x); +} diff --git a/tools/number.ts b/tools/number.ts new file mode 100644 index 0000000..28b110f --- /dev/null +++ b/tools/number.ts @@ -0,0 +1,4 @@ +/* eslint-disable import/prefer-default-export */ +import { round } from 'lodash'; + +export { round }; diff --git a/yarn.lock b/yarn.lock index 2b97dfc..dc980c5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2234,6 +2234,11 @@ dayjs@1.x: resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.1.tgz#90b33a3dda3417258d48ad2771b415def6545eb0" integrity sha512-ER7EjqVAMkRRsxNCC5YqJ9d9VQYuWdGt7aiH2qA5R5wt8ZmWaP2dLUSIK6y/kVzLMlmh1Tvu5xUf4M/wdGJ5KA== +dayjs@^1.11.2: + version "1.11.2" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.2.tgz#fa0f5223ef0d6724b3d8327134890cfe3d72fbe5" + integrity sha512-F4LXf1OeU9hrSYRPTTj/6FbO4HTjPKXvEIC1P2kcnFurViINCVk3ZV0xAS3XVx9MkMsXbbqlK6hjseaYbgKEHw== + debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"