diff --git a/craco.config.js b/craco.config.js index 2fdf2da..49d3f98 100644 --- a/craco.config.js +++ b/craco.config.js @@ -1,7 +1,17 @@ const CracoAntDesignPlugin = require('craco-antd'); const colors = require('./src/client/UIKit/colors'); +const { ProvidePlugin } = require('webpack'); +const CracoEsbuildPlugin = require('craco-esbuild'); + module.exports = { + webpack: { + plugins: [ + new ProvidePlugin({ + React: 'react', + }), + ], + }, plugins: [ { plugin: CracoAntDesignPlugin, @@ -14,6 +24,7 @@ module.exports = { }, }, }, + { plugin: CracoEsbuildPlugin }, ], babel: { plugins: [ @@ -26,6 +37,7 @@ module.exports = { }, }, ], + ['babel-plugin-styled-components'], ], }, }; diff --git a/package.json b/package.json index fabb102..de1b9de 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,10 @@ "@testing-library/user-event": "^12.1.10", "antd": "^4.15.5", "axios": "^0.21.1", + "babel-plugin-styled-components": "^1.13.2", "babel-plugin-transform-imports": "^2.0.0", "craco-antd": "^1.19.0", + "craco-esbuild": "^0.3.4", "dayjs": "^1.10.4", "graphql": "^15.5.0", "lodash": "^4.17.21", @@ -28,7 +30,8 @@ "typescript": "^4.2.4", "use-debounce": "^6.0.1", "uuid": "^8.3.2", - "validator": "^13.5.2" + "validator": "^13.5.2", + "webpack": "4.44.2" }, "devDependencies": { "@storybook/addon-actions": "^6.2.9", diff --git a/src/client/Components/Calculation/ELT/Content/Components/InsTable.tsx b/src/client/Components/Calculation/ELT/Content/Components/InsTable.tsx index c3269cf..b9015d2 100644 --- a/src/client/Components/Calculation/ELT/Content/Components/InsTable.tsx +++ b/src/client/Components/Calculation/ELT/Content/Components/InsTable.tsx @@ -5,7 +5,7 @@ import { Box } from 'client/UIKit/grid'; import mq from 'client/UIKit/mq'; import { toJS } from 'mobx'; import { observer } from 'mobx-react-lite'; -import React, { useEffect } from 'react'; +import { FC, useEffect } from 'react'; import styled from 'styled-components'; const TableWrapper = styled(Box)` @@ -48,4 +48,4 @@ export default observer(({ insType, selectKey, selectedKey, tableConfig }) => { > ); -}) as React.FC; +}) as FC; diff --git a/src/client/Components/Calculation/ELT/Content/Kasko/lib/composeRequest.ts b/src/client/Components/Calculation/ELT/Content/Kasko/lib/composeRequest.ts index 530af7c..b7a920a 100644 --- a/src/client/Components/Calculation/ELT/Content/Kasko/lib/composeRequest.ts +++ b/src/client/Components/Calculation/ELT/Content/Kasko/lib/composeRequest.ts @@ -29,7 +29,7 @@ const mapVehicleUsage = { const mapCategory = { 100000000: 'A', 100000001: 'B', - 100000002: 'C2', + // 100000002: 'C2', 100000003: 'D', 100000004: 'E1', }; @@ -39,30 +39,74 @@ const mapInfuranceToLesseSubjectType = { 100000001: 2, }; +const mapLeaseObjectUseForToIndustry = { + 100000014: 30, + 100000015: 15, + 100000016: 3, + 100000017: 26, + 100000018: 2, + 100000019: 6, +}; + const getSpecified = value => !isNull(value); export default function (this: ICalculationStore) { const region = this.getOption('selectLegalClientRegion'); const city = this.getOption('selectLegalClientTown'); const kladr = get(city, 'evo_kladr_id') || get(region, 'evo_kladr_id'); - const brandId = this.getOption('selectBrand')?.evo_id; - const modelId = this.getOption('selectModel')?.evo_id; + const leaseObjectType = this.getOption('selectLeaseObjectType'); + const leaseObjectCategory = this.getValue('leaseObjectCategory'); + + const brand = this.getOption('selectBrand'); + let brandId = brand?.evo_id; + const model = this.getOption('selectModel'); + let modelId = model?.evo_id; const isNew = !this.getValue('leaseObjectUsed'); const vehicleYear = this.getValue('leaseObjectYear'); const power = this.getValue('leaseObjectMotorPower'); const powerSpecified = getSpecified(power); + let country = 0, + countrySpecified = false; + if (leaseObjectCategory === 100000002 || leaseObjectType?.evo_id === '9') + if (brand?.evo_brand_owner === 100000001) { + country = 1; + countrySpecified = true; + } + let engineType = '5'; const engineTypeValue = this.getValue('engineType'); if (engineTypeValue) { engineType = mapEngineType[engineTypeValue]; } - const duration = this.getValue('leasingPeriod'); + let duration = this.getValue('leasingPeriod'); + if (duration < 12) { + duration = 12; + } const cost = this.getValue('leaseObjectPrice') - this.getValue('supplierDiscountRub'); + let notConfirmedGlassesDamages, + notConfirmedGlassesDamagesSpecified = false, + notConfirmedDamages, + notConfirmedDamagesSpecified = false, + selfIgnition = false, + selfIgnitionSpecified = false, + outsideRoads, + outsideRoadsSpecified = false; + if (leaseObjectCategory === 100000002 || leaseObjectType?.evo_id === '9') { + notConfirmedGlassesDamages = 3; + notConfirmedGlassesDamagesSpecified = true; + notConfirmedDamages = 2; + notConfirmedDamagesSpecified = true; + // selfIgnition = true; + selfIgnitionSpecified = true; + outsideRoads = true; + outsideRoadsSpecified = true; + } + const franchise = parseInt(this.getValue('insFranchise') || 0); const franchiseSpecified = getSpecified(franchise); const puuMark = this.getOption('selectGPSBrand')?.evo_id; @@ -74,6 +118,8 @@ export default function (this: ICalculationStore) { sex = '0', driversCount = 1; + const risk = leaseObjectType?.evo_id === '9' ? 3 : 0; + if (this.getValue('insUnlimitDrivers')) { age = 18; experience = 0; @@ -82,7 +128,7 @@ export default function (this: ICalculationStore) { const sexSpecified = getSpecified(sex); let maxAllowedMass = 0; - if (this.getValue('leaseObjectCategory') === 100000002) { + if (leaseObjectCategory === 100000002) { maxAllowedMass = this.getValue('maxMass'); } const maxAllowedMassSpecified = getSpecified(maxAllowedMass); @@ -101,12 +147,27 @@ export default function (this: ICalculationStore) { const vehicleUsageSpecified = getSpecified(vehicleUsage); let seatingCapacity = 0; - if (this.getValue('leaseObjectCategory') === 100000003) { + if (leaseObjectCategory === 100000003) { seatingCapacity = this.getValue('countSeats'); } const seatingCapacitySpecified = getSpecified(seatingCapacity); - const category = mapCategory[this.getValue('leaseObjectCategory')]; + let category = mapCategory[leaseObjectCategory]; + if (leaseObjectCategory === 100000002) + switch (leaseObjectType?.evo_id) { + case '7': { + category = 'C1'; + break; + } + case '3': { + category = 'C3'; + break; + } + default: { + category = 'C2'; + break; + } + } const classification = [100000002, 100000003, 100000004].includes( this.getValue('leaseObjectCategory'), @@ -119,11 +180,34 @@ export default function (this: ICalculationStore) { const infuranceOPF = this.getValue('infuranceOPF'); const lesseSubjectType = get(mapInfuranceToLesseSubjectType, infuranceOPF, 0); + let specialMachineryType = 0, + specialMachineryIndustry = 0, + specialMachineryMover = 0; + if (leaseObjectType?.evo_id === '9') { + specialMachineryType = parseInt( + model?.evo_vehicle_body_typeidData?.evo_id_elt || '0', + ); + specialMachineryIndustry = + mapLeaseObjectUseForToIndustry[leaseObjectUseForValue]; + specialMachineryMover = + leaseObjectType.evo_id === '9' && model?.evo_running_gear === 100000001 + ? 2 + : 1; + } + return { preparams: { kladr, brandId, modelId, + specialMachinery: { + type: specialMachineryType, + typeSpecified: getSpecified(specialMachineryType), + industry: specialMachineryIndustry, + industrySpecified: getSpecified(specialMachineryIndustry), + mover: specialMachineryMover, + moverSpecified: getSpecified(specialMachineryMover), + }, }, ELTParams: { currency: 'RUR', @@ -137,7 +221,8 @@ export default function (this: ICalculationStore) { engineVolume: 0, engineVolumeSpecified: true, KPPTypeId: 1, - BodyType: 9, + country, + countrySpecified, }, duration, bankId: '245', @@ -148,6 +233,14 @@ export default function (this: ICalculationStore) { STOA: '0', OfficialDealerSpecified: true, OfficialDealer: true, + notConfirmedGlassesDamages, + notConfirmedGlassesDamagesSpecified, + notConfirmedDamages, + notConfirmedDamagesSpecified, + selfIgnition, + selfIgnitionSpecified, + outsideRoads, + outsideRoadsSpecified, PUUs: puuMark && [ { mark: puuMark, @@ -156,7 +249,9 @@ export default function (this: ICalculationStore) { }, ], driversCount, - risk: 0, + approvedDriving: 2, + approvedDrivingSpecified: true, + risk, payType: '0', vehicle: { maxAllowedMass, diff --git a/src/client/Components/Calculation/ELT/Content/Kasko/lib/convertEltResult.js b/src/client/Components/Calculation/ELT/Content/Kasko/lib/convertEltResult.js index e9d6734..a21eb02 100644 --- a/src/client/Components/Calculation/ELT/Content/Kasko/lib/convertEltResult.js +++ b/src/client/Components/Calculation/ELT/Content/Kasko/lib/convertEltResult.js @@ -14,7 +14,7 @@ export default function (resultCompany, key, { leasingPeriod }) { const sumsFromResult = pick(resultCompany, ['totalFranchise'], 0); const kaskoSumSource = - leasingPeriod < 16 ? 'kaskoSum' : 'paymentPeriods[0].kaskoSum'; + leasingPeriod <= 16 ? 'kaskoSum' : 'paymentPeriods[0].kaskoSum'; const kaskoSum = get(resultCompany, kaskoSumSource, 0); return { diff --git a/src/client/Components/Calculation/ELT/Content/Kasko/lib/validation.ts b/src/client/Components/Calculation/ELT/Content/Kasko/lib/validation.ts index 5b445b0..8b1c844 100644 --- a/src/client/Components/Calculation/ELT/Content/Kasko/lib/validation.ts +++ b/src/client/Components/Calculation/ELT/Content/Kasko/lib/validation.ts @@ -22,12 +22,22 @@ export const requiredFields: ElementsNames[] = [ export const conditions: TElements = { selectLeaseObjectType: calculationStore => { const leaseObjectType = calculationStore.getOption('selectLeaseObjectType'); - if (['9', '11'].includes(leaseObjectType?.evo_id || '')) { + if (leaseObjectType?.evo_id && ['11'].includes(leaseObjectType?.evo_id)) { return { isValid: false, message: `По данному Типу предмета лизинга возможен только индивидуальный запрос тарифов КАСКО и ОСАГО. Просьба обратиться на адрес strakhovka@evoleasing.ru`, }; } + + if ( + leaseObjectType?.evo_id && + !['1', '2', '3', '7', '9'].includes(leaseObjectType?.evo_id) + ) { + return { + isValid: false, + message: `Для выбранной категории ТС расчет в ЭЛТ недоступен`, + }; + } return { isValid: true, }; @@ -68,7 +78,7 @@ export const conditions: TElements = { const leaseObjectType = calculationStore.getOption('selectLeaseObjectType'); if (!leaseObjectCategory) { - if (['6', '10'].includes(leaseObjectType?.evo_id || '')) { + if (['6', '9', '10'].includes(leaseObjectType?.evo_id || '')) { return { isValid: true, }; @@ -101,6 +111,18 @@ export const conditions: TElements = { isValid: true, }; }, + cbxInsDecentral: calculationStore => { + const insDecentral = calculationStore.getValue('insDecentral'); + if (insDecentral) { + return { + isValid: false, + message: 'Децентрализованное страхование не может быть расчитано в ЭЛТ', + }; + } + return { + isValid: true, + }; + }, }; export const resetFields: ElementsNames[] = [ diff --git a/src/client/Components/Calculation/ELT/Content/Osago/lib/composeRequest.ts b/src/client/Components/Calculation/ELT/Content/Osago/lib/composeRequest.ts index 12ce35c..597e2b2 100644 --- a/src/client/Components/Calculation/ELT/Content/Osago/lib/composeRequest.ts +++ b/src/client/Components/Calculation/ELT/Content/Osago/lib/composeRequest.ts @@ -1,5 +1,6 @@ import { currentDate } from 'core/tools/date'; import { ICalculationStore } from 'core/types/Calculation/Store'; +import { IAccount } from 'core/types/Entities/crmEntities'; import { get, isNull } from 'lodash'; const mapCategory = { @@ -38,11 +39,20 @@ const mapSubCategoryBuilder = (leaseObjectUseFor, maxMass, countSeats) => ({ const getSpecified = value => !isNull(value); -export default function (this: ICalculationStore) { +export default function (this: ICalculationStore, company: IAccount) { const city = this.getOption('selectTownRegistration'); let kladr = '7700000000000'; if (this.getValue('objectRegistration') === 100000001) { - kladr = get(city, 'evo_kladr_id', kladr); + kladr = city?.evo_kladr_id || kladr; + } else { + if (company.evo_legal_region_calc === true) { + const legalClientRegion = this.getOption('selectLegalClientRegion'); + const legalClientTown = this.getOption('selectLegalClientTown'); + kladr = + legalClientTown?.evo_kladr_id || + legalClientRegion?.evo_kladr_id || + kladr; + } } const brandId = this.getOption('selectBrand')?.evo_id; const modelId = this.getOption('selectModel')?.evo_id; @@ -51,10 +61,9 @@ export default function (this: ICalculationStore) { const model = this.getOption('selectGPSModel')?.evo_id; const vehicleYear = this.getValue('leaseObjectYear') + ''; const leaseObjectCategory = this.getValue('leaseObjectCategory'); - const vehiclePower = - leaseObjectCategory === 100000001 - ? parseFloat(this.getValue('leaseObjectMotorPower') || '0') - : '0'; + const vehiclePower = parseFloat( + this.getValue('leaseObjectMotorPower') || '0', + ); let category = '0'; if (Object.keys(mapCategory).includes(`${leaseObjectCategory}`)) { @@ -90,7 +99,7 @@ export default function (this: ICalculationStore) { const address = { resident: 1, - country: 'Российская Федерация', + country: 'Россия', region: 'Москва', // district: '0', city: 'Москва', diff --git a/src/client/Components/Calculation/ELT/Content/Osago/lib/validation.ts b/src/client/Components/Calculation/ELT/Content/Osago/lib/validation.ts index 5ed8295..de1f572 100644 --- a/src/client/Components/Calculation/ELT/Content/Osago/lib/validation.ts +++ b/src/client/Components/Calculation/ELT/Content/Osago/lib/validation.ts @@ -22,7 +22,7 @@ export const requiredFields: ElementsNames[] = [ 'radioInfuranceOPF', ]; -const conditions: TElements = { +const osagoConditions: TElements = { selectTownRegistration: calculationStore => { const objectRegistration = calculationStore.getValue('objectRegistration'); if (objectRegistration === 100000001) { @@ -40,6 +40,11 @@ const conditions: TElements = { }, }; +const conditions = Object.assign( + osagoConditions, + omit(kaskoConditions, ['selectEngineType']), +); + export const resetFields: ElementsNames[] = [ ...requiredFields, ...(Object.keys(conditions) as ElementsNames[]), @@ -51,8 +56,5 @@ export const resetFields: ElementsNames[] = [ export default { requiredFields, - conditions: Object.assign( - conditions, - omit(kaskoConditions, ['selectEngineType']), - ), + conditions, }; diff --git a/src/client/Components/Calculation/ELT/Content/lib/requests.ts b/src/client/Components/Calculation/ELT/Content/lib/requests.ts index aeb650b..1ad6c04 100644 --- a/src/client/Components/Calculation/ELT/Content/lib/requests.ts +++ b/src/client/Components/Calculation/ELT/Content/lib/requests.ts @@ -17,15 +17,14 @@ export const fetchData = (insType: string, composeRequest, convertEltResult) => sources[insType] = CancelToken.source(); const { ELTStore } = this.stores; - const request = composeRequest.call(this); - const evo_id_elt_fieldName = map_evo_id_elt_FieldName[insType]; + const evo_id_elt_fieldName = map_evo_id_elt_FieldName[insType](this); const requests = ELTStore[insType].list.map( - (company: IAccount, i: number) => { - //@ts-ignore + (company: IAccount & { isFetching: boolean }, i: number) => { company.isFetching = true; return new Promise((resolve, reject) => { + const request = composeRequest.call(this, company); ELTService[insType] .getCalculation( { @@ -51,14 +50,13 @@ export const fetchData = (insType: string, composeRequest, convertEltResult) => i, Object.assign(company, converted), ); - resolve(); }) .catch(err => { reject(err); }) .finally(() => { - //@ts-ignore company.isFetching = false; + resolve(); }); }); }, diff --git a/src/client/Components/Calculation/ELT/Content/lib/resetIns.ts b/src/client/Components/Calculation/ELT/Content/lib/resetIns.ts index eb16d5a..b2a1dbb 100644 --- a/src/client/Components/Calculation/ELT/Content/lib/resetIns.ts +++ b/src/client/Components/Calculation/ELT/Content/lib/resetIns.ts @@ -9,15 +9,20 @@ const mapInsType = { }; export const map_evo_id_elt_FieldName = { - kasko: 'evo_id_elt', - osago: 'evo_id_elt_osago', + kasko: (calculationStore: ICalculationStore) => + calculationStore.getOption('selectLeaseObjectType')?.evo_id !== '9' + ? 'evo_id_elt' + : 'evo_id_elt_smr', + osago: (_: ICalculationStore) => 'evo_id_elt_osago', }; export const initFields = [ 'evo_id_elt_osago', + 'evo_id_elt_smr', 'evo_id_elt', 'name', 'accountid', + 'evo_legal_region_calc', ]; export function initIns(this: ICalculationStore, insType) { @@ -30,13 +35,12 @@ export function initIns(this: ICalculationStore, insType) { } const { ELTStore } = this.stores; const list: TCRMEntity[] = []; - const evo_id_elt_fieldName = map_evo_id_elt_FieldName[insType]; + const evo_id_elt_fieldName = map_evo_id_elt_FieldName[insType](this); insuranceCompanies.forEach(company => { if ( company && company[evo_id_elt_fieldName] && - company.evo_type_ins_policy && - company.evo_type_ins_policy.includes(mapInsType[insType]) + company?.evo_type_ins_policy?.includes(mapInsType[insType]) ) { const companyData = pick(company, initFields, ''); list.push(companyData); diff --git a/src/client/Components/Calculation/ELT/Content/lib/validation.ts b/src/client/Components/Calculation/ELT/Content/lib/validation.ts index fcebf32..5a68ffe 100644 --- a/src/client/Components/Calculation/ELT/Content/lib/validation.ts +++ b/src/client/Components/Calculation/ELT/Content/lib/validation.ts @@ -10,6 +10,7 @@ import CONDITIONS from 'core/validation/conditions'; import { convertToValidationResult, getValue, + showValidationMessages, validate, ValidationCondition, } from 'core/validation/validate'; @@ -59,27 +60,14 @@ export default function (this: ICalculationStore, validation: ELTValidation) { if (customConditions) { const customConditionsResult = validate(this, customConditions); - let messages: string[] = []; - (Object.keys(customConditionsResult) as ElementsNames[]).forEach( - elementName => { - const validationResult = customConditionsResult[elementName]; - if (validationResult?.isValid === false && validationResult.message) { - messages.push(validationResult.message); - } - }, + const { hasMessages } = showValidationMessages( + customConditionsResult, + 'Ошибка во время расчета ЭЛТ', ); - if (messages && messages.length > 0) { - messages.forEach(message => { - if (message) - openNotification({ - type: 'error', - title: 'Ошибка во время расчета ЭЛТ', - description: message, - })(); - }); + if (hasMessages) { return false; } - } - return true; + return true; + } } diff --git a/src/client/Components/Calculation/InsuranceTag.jsx b/src/client/Components/Calculation/InsuranceTag.jsx index 187c339..0d470ee 100644 --- a/src/client/Components/Calculation/InsuranceTag.jsx +++ b/src/client/Components/Calculation/InsuranceTag.jsx @@ -1,7 +1,7 @@ import Tag from 'client/Elements/Tag'; import { useStores } from 'client/hooks/useStores'; +import { Flex } from 'client/UIKit/grid'; import { observer } from 'mobx-react-lite'; -import { Flex } from 'rebass'; const InsuranceTag = observer(() => { const { diff --git a/src/client/Components/Result.jsx b/src/client/Components/Result.jsx index 93c3d0c..01086ce 100644 --- a/src/client/Components/Result.jsx +++ b/src/client/Components/Result.jsx @@ -2,7 +2,12 @@ import { Result } from 'antd'; export default { 404: () => , - 500: () => ( - + 500: props => ( + ), }; diff --git a/src/client/Containers/Calculation/Results/index.jsx b/src/client/Containers/Calculation/Results/index.jsx index 61304d4..c18eb7d 100644 --- a/src/client/Containers/Calculation/Results/index.jsx +++ b/src/client/Containers/Calculation/Results/index.jsx @@ -1,13 +1,10 @@ -import { renderGroups } from 'client/Containers/Calculation/lib/renderSections'; +import { renderSections } from 'client/Containers/Calculation/lib/renderSections'; import Background from 'client/Elements/Background'; -import { Flex } from 'client/UIKit/grid'; import { calculationResults } from './resultsList'; const Results = props => ( - - {renderGroups({ groups: calculationResults })} - + {renderSections({ sectionsList: calculationResults })} ); diff --git a/src/client/Containers/Calculation/Results/resultsList.ts b/src/client/Containers/Calculation/Results/resultsList.ts index 3818e48..1f6a019 100644 --- a/src/client/Containers/Calculation/Results/resultsList.ts +++ b/src/client/Containers/Calculation/Results/resultsList.ts @@ -1,28 +1,51 @@ -import { IGroup } from 'core/types/Calculation/components'; +import { ISection } from 'core/types/Calculation/components'; -export const calculationResults: IGroup[] = [ +export const calculationResults: ISection[] = [ { - style: { columnsNumber: 1 }, - blocks: [ + title: 'График платежей', + groups: [ { - title: 'Результаты', - elements: [ - 'labelResultTotalGraphwithNDS', - 'labelResultPlPrice', - 'labelResultPriceUpPr', - 'labelResultIRRGraphPerc', - 'labelResultIRRNominalPerc', - 'labelResultInsKasko', - 'labelResultInsOsago', - 'labelResultDopProdSum', - 'labelResultFirstPayment', - 'labelResultLastPayment', - 'labelResultTerm', - 'labelResultAB_FL', - 'labelResultAB_UL', - 'labelResultBonusMPL', - 'labelResultDopMPLLeasing', - 'labelResultBonusDopProd', + style: { columnsNumber: 1 }, + blocks: [ + { + elements: ['tableResults'], + }, + ], + }, + ], + }, + { + title: 'Результаты', + groups: [ + { + style: { columnsNumber: 1 }, + blocks: [ + { + style: { columnsNumber: 2 }, + elementStyle: { + head: { + whiteSpace: 'normal', + }, + }, + elements: [ + 'labelResultTotalGraphwithNDS', + 'labelResultPlPrice', + 'labelResultPriceUpPr', + 'labelResultIRRGraphPerc', + 'labelResultIRRNominalPerc', + 'labelResultInsKasko', + 'labelResultInsOsago', + 'labelResultDopProdSum', + 'labelResultFirstPayment', + 'labelResultLastPayment', + 'labelResultTerm', + 'labelResultAB_FL', + 'labelResultAB_UL', + 'labelResultBonusMPL', + 'labelResultDopMPLLeasing', + 'labelResultBonusDopProd', + ], + }, ], }, ], diff --git a/src/client/Containers/Calculation/ResultsTable/index.jsx b/src/client/Containers/Calculation/ResultsTable/index.jsx deleted file mode 100644 index e1e68fd..0000000 --- a/src/client/Containers/Calculation/ResultsTable/index.jsx +++ /dev/null @@ -1,12 +0,0 @@ -import { renderGroups } from 'client/Containers/Calculation/lib/renderSections'; -import Background from 'client/Elements/Background'; -import { Flex } from 'client/UIKit/grid'; -import { resultsTable } from './resultsTableList'; - -const Results = props => ( - - {renderGroups({ groups: resultsTable })} - -); - -export default Results; diff --git a/src/client/Containers/Calculation/ResultsTable/resultsTableList.ts b/src/client/Containers/Calculation/ResultsTable/resultsTableList.ts deleted file mode 100644 index c3f84fb..0000000 --- a/src/client/Containers/Calculation/ResultsTable/resultsTableList.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { IGroup } from 'core/types/Calculation/components'; - -export const resultsTable: IGroup[] = [ - { - style: { columnsNumber: 1 }, - blocks: [ - { - title: 'График платежей', - elements: ['tableResults'], - }, - ], - }, -]; diff --git a/src/client/Containers/Calculation/Sections/sectionsList.ts b/src/client/Containers/Calculation/Sections/sectionsList.ts index 0f923ad..69ac3a9 100644 --- a/src/client/Containers/Calculation/Sections/sectionsList.ts +++ b/src/client/Containers/Calculation/Sections/sectionsList.ts @@ -82,6 +82,7 @@ const sections: ISection[] = [ 'tbxSupplierDiscountPerc', 'radioBalanceHolder', 'tbxSaleBonus', + 'selectSubsidy', ], }, { @@ -93,17 +94,10 @@ const sections: ISection[] = [ 'tbxLastPaymentPerc', 'tbxLastPaymentRub', 'tbxLeasingPeriod', + 'labelSubsidySum', ], }, - { - title: 'Параметры графика платежей', - elements: [ - 'radioGraphType', - 'selectSeasonType', - 'tbxParmentsDecreasePercent', - 'selectHighSeasonStart', - ], - }, + { // title: 'Параметры расчета', elements: [ @@ -113,6 +107,26 @@ const sections: ISection[] = [ }, ], }, + ], + }, + { + title: 'Платежи', + groups: [ + { + blocks: [ + { + // title: 'Параметры графика платежей', + elements: ['radioGraphType'], + }, + { + elements: [ + 'selectSeasonType', + 'tbxParmentsDecreasePercent', + 'selectHighSeasonStart', + ], + }, + ], + }, { style: { columnsNumber: 1 }, blocks: [ @@ -137,7 +151,7 @@ const sections: ISection[] = [ ], }, { - title: ' ', + title: ' ', elements: [ 'labelLeaseObjectRisk', 'labelDepreciationGroup', @@ -283,21 +297,21 @@ const sections: ISection[] = [ }, { elements: [ - 'cbxInsUnlimitDrivers', - 'tbxInsAgeDrivers', - 'tbxInsExpDrivers', + // 'cbxInsUnlimitDrivers', + // 'tbxInsAgeDrivers', + // 'tbxInsExpDrivers', + 'selectGPSBrand', + 'selectGPSModel', + 'tbxInsKaskoPriceLeasePeriod', 'cbxWithTrailer', - 'tbxINNForCalc', // 'btnDriversApplication', ], }, { elements: [ - 'selectGPSBrand', - 'selectGPSModel', 'selectLegalClientRegion', 'selectLegalClientTown', - 'tbxInsKaskoPriceLeasePeriod', + 'tbxINNForCalc', ], }, ], @@ -368,6 +382,7 @@ const sections: ISection[] = [ { elements: [ 'selectTechnicalCard', + // 'selectFuelCard', 'selectInsNSIB', 'radioRequirementTelematic', 'selectTracker', @@ -382,20 +397,22 @@ const sections: ISection[] = [ title: 'Создание КП', groups: [ { + style: { columnsNumber: 1 }, blocks: [ { + style: { columnsNumber: 2 }, + elementStyle: { + head: { + whiteSpace: 'normal', + }, + }, elements: [ 'cbxLastPaymentRedemption', 'cbxPriceWithDiscount', 'cbxFullPriceWithDiscount', 'cbxCostIncrease', - ], - }, - { - elements: ['cbxInsurance', 'cbxRegistrationQuote'], - }, - { - elements: [ + 'cbxInsurance', + 'cbxRegistrationQuote', 'cbxTechnicalCardQuote', 'cbxNSIB', 'cbxQuoteRedemptionGraph', @@ -404,24 +421,21 @@ const sections: ISection[] = [ ], }, { - style: { columnsNumber: 2 }, + style: { columnsNumber: 1 }, blocks: [ { - elements: ['tbxQuoteName'], - }, - { - elements: ['radioQuoteContactGender'], + style: { columnsNumber: 2 }, + elements: ['tbxQuoteName', 'radioQuoteContactGender'], }, ], }, { - style: { columnsNumber: 2 }, + style: { columnsNumber: 1 }, blocks: [ { - elements: ['btnCreateKP'], - }, - { - elements: ['linkDownloadKp'], + style: { columnsNumber: 2 }, + + elements: ['btnCreateKP', 'linkDownloadKp'], }, ], }, diff --git a/src/client/Containers/Calculation/index.jsx b/src/client/Containers/Calculation/index.jsx index e14131b..dc19e64 100644 --- a/src/client/Containers/Calculation/index.jsx +++ b/src/client/Containers/Calculation/index.jsx @@ -1,14 +1,14 @@ import Result from 'client/Components/Result'; import Spinner from 'client/Components/Spinner'; +import Button from 'client/Elements/Button'; import { CenterContent } from 'client/Elements/Wrapper'; import { useFetch } from 'client/hooks/Calculation/useFetch'; -import { Box, Flex } from 'client/UIKit/grid'; +import { Box } from 'client/UIKit/grid'; import mq from 'client/UIKit/mq'; import styled from 'styled-components'; import Info from './Info'; import fetchData from './lib/fetchData'; import Results from './Results'; -import ResultsTable from './ResultsTable'; import Sections from './Sections'; const Grid = styled(Box)` @@ -25,15 +25,8 @@ const Grid = styled(Box)` `} `; -const Middle = () => ( - - - - -); - const Calculation = () => { - const { isLoading, error } = useFetch({ fetchData }); + const { isLoading, error, fetch } = useFetch({ fetchData }); if (isLoading) { return ( @@ -45,14 +38,18 @@ const Calculation = () => { if (error) { const ServerError = Result[500]; - return ; + return ( + ]} + /> + ); } return ( - - + + ); }; diff --git a/src/client/Containers/Calculation/lib/buildElement.js b/src/client/Containers/Calculation/lib/buildElement.js index e8b6652..205b3d8 100644 --- a/src/client/Containers/Calculation/lib/buildElement.js +++ b/src/client/Containers/Calculation/lib/buildElement.js @@ -6,7 +6,7 @@ import { withValue, } from 'client/hocs/Calculation'; import { ElementType } from 'core/types/Calculation/Store/elements'; -import { omit } from 'lodash'; +import { pick } from 'lodash'; import elementsActions from './elements/actions'; import elementsComponents from './elements/components'; import elementsComputedValues from './elements/computedValues'; @@ -23,7 +23,7 @@ export function buildElement(elementName, elementProps = {}) { case ElementType.Table: { return withTable(Component)({ name: elementName, - ...omit(tables[elementName], ['columns', 'rows', 'options']), + ...pick(tables[elementName], ['options', 'callbacks', 'params']), }); } case ElementType.Action: { diff --git a/src/client/Containers/Calculation/lib/elements/components.ts b/src/client/Containers/Calculation/lib/elements/components.ts index c67448f..f68926e 100644 --- a/src/client/Containers/Calculation/lib/elements/components.ts +++ b/src/client/Containers/Calculation/lib/elements/components.ts @@ -1,10 +1,10 @@ import ELT from 'client/Components/Calculation/ELT'; import Button from 'client/Elements/Button'; import Checkbox from 'client/Elements/Checkbox'; -import Download from 'client/Elements/Download'; import Input from 'client/Elements/Input'; import InputNumber from 'client/Elements/InputNumber'; import Label from 'client/Elements/Label'; +import Link from 'client/Elements/Link'; import Radio from 'client/Elements/Radio'; import Select from 'client/Elements/Select'; import Switch from 'client/Elements/Switch'; @@ -156,7 +156,7 @@ const elementsComponents: TElements = { labelResultBonusMPL: Label, labelResultDopMPLLeasing: Label, labelResultBonusDopProd: Label, - linkDownloadKp: Download, + linkDownloadKp: Link, tbxMileage: InputNumber, radioCalcType: Radio, tbxTotalPayments: InputNumber, @@ -171,6 +171,9 @@ const elementsComponents: TElements = { labelRegistrationDescription: Label, selectLegalClientRegion: Select, selectLegalClientTown: Select, + selectSubsidy: Select, + selectFuelCard: Select, + labelSubsidySum: Label, }; const tablesComponents: StoreTables = { diff --git a/src/client/Containers/Calculation/lib/elements/elementsProps.ts b/src/client/Containers/Calculation/lib/elements/elementsProps.ts index 8512ce3..8a5a28b 100644 --- a/src/client/Containers/Calculation/lib/elements/elementsProps.ts +++ b/src/client/Containers/Calculation/lib/elements/elementsProps.ts @@ -1,5 +1,8 @@ import DownloadOutlined from '@ant-design/icons/lib/icons/DownloadOutlined'; import InsuranceTag from 'client/Components/Calculation/InsuranceTag'; +import Link from 'client/Elements/Link'; +import buildTooltip from 'client/Elements/Tooltip'; +import { withLink } from 'client/hocs/Calculation'; import { MAX_FRANCHISE } from 'core/constants/stores/Calculation/limits'; import { currentYear } from 'core/tools/date'; import { formatMoney, formatNumber } from 'core/tools/format'; @@ -107,7 +110,7 @@ const elementsProps: TElements = { tbxFirstPaymentPerc: { min: '0', max: '50', - precision: 2, + precision: 4, formatter: formatNumber, }, tbxFirstPaymentRub: { @@ -217,45 +220,45 @@ const elementsProps: TElements = { showSearch: true, }, tbxDealerRewardSumm: { - min: '0.0', - max: '20.0', - step: '0.1', - precision: 1, + min: '0.00', + max: '20.00', + step: '0.10', + precision: 2, formatter: formatNumber, }, tbxDealerBrokerRewardSumm: { - min: '0.0', - max: '20.0', - step: '0.1', - precision: 1, + min: '0.00', + max: '20.00', + step: '0.10', + precision: 2, formatter: formatNumber, }, tbxIndAgentRewardSumm: { - min: '0.0', - max: '20.0', - step: '0.1', - precision: 1, + min: '0.00', + max: '20.00', + step: '0.10', + precision: 2, formatter: formatNumber, }, tbxCalcDoubleAgentRewardSumm: { - min: '0.0', - max: '20.0', - step: '0.1', - precision: 1, + min: '0.00', + max: '20.00', + step: '0.10', + precision: 2, formatter: formatNumber, }, tbxCalcBrokerRewardSum: { - min: '0.0', - max: '20.0', - step: '0.1', - precision: 1, + min: '0.00', + max: '20.00', + step: '0.10', + precision: 2, formatter: formatNumber, }, tbxFinDepartmentRewardSumm: { - min: '0.0', - max: '20.0', - step: '0.1', - precision: 1, + min: '0.00', + max: '20.00', + step: '0.10', + precision: 2, formatter: formatNumber, }, radioInsKaskoType: { @@ -291,7 +294,7 @@ const elementsProps: TElements = { showSearch: true, }, radioRequirementTelematic: { - style: 'button', + // style: 'button', }, radioQuoteContactGender: { style: 'button', @@ -313,21 +316,47 @@ const elementsProps: TElements = { tbxImporterRewardPerc: { min: '0.00', max: '99.99', - step: '0.1', + step: '0.10', + precision: 2, }, tbxImporterRewardRub: { - min: '0', - max: '1000000000', + min: '0.00', + max: '1000000000.00', step: '10000.00', + precision: 2, }, selectLead: { showSearch: true, + sub: { + Component: withLink(Link)({ + name: 'leadUrl', + text: 'Открыть в CRM', + urlName: 'leadUrl', + type: 'link', + }), + }, }, selectOpportunity: { showSearch: true, + sub: { + Component: withLink(Link)({ + name: 'leadUrl', + text: 'Открыть в CRM', + urlName: 'opportunityUrl', + type: 'link', + }), + }, }, selectQuote: { showSearch: true, + sub: { + Component: withLink(Link)({ + name: 'leadUrl', + text: 'Открыть в CRM', + urlName: 'quoteUrl', + type: 'link', + }), + }, }, btnCalculate: { text: 'Рассчитать график', @@ -381,8 +410,10 @@ const elementsProps: TElements = { max: 9999999, precision: 2, tooltip: { - title: 'Без учета налога на роскошь', - placement: 'topLeft', + Component: buildTooltip({ + title: 'Без учета налога на роскошь', + placement: 'topLeft', + }), }, }, tbxVehicleTaxInLeasingPeriod: { @@ -401,7 +432,7 @@ const elementsProps: TElements = { // }, }, tableInsurance: { - tag: { + sub: { Component: InsuranceTag, }, }, @@ -421,7 +452,7 @@ const elementsProps: TElements = { }, }; -const resultElementsProps: TElements = Object.assign( +const labelElementsProps: TElements = Object.assign( {}, [ 'labelResultTotalGraphwithNDS', @@ -436,6 +467,7 @@ const resultElementsProps: TElements = Object.assign( 'labelResultBonusMPL', 'labelResultDopMPLLeasing', 'labelResultBonusDopProd', + 'labelSubsidySum', ].reduce( (ac, a) => ({ ...ac, @@ -457,4 +489,4 @@ const resultElementsProps: TElements = Object.assign( {}, ), ); -export default Object.assign(elementsProps, resultElementsProps); +export default Object.assign(elementsProps, labelElementsProps); diff --git a/src/client/Containers/Calculation/lib/elements/tables/payments.ts b/src/client/Containers/Calculation/lib/elements/tables/payments.ts index 9375f28..c2c33c4 100644 --- a/src/client/Containers/Calculation/lib/elements/tables/payments.ts +++ b/src/client/Containers/Calculation/lib/elements/tables/payments.ts @@ -14,7 +14,7 @@ const { PERIODS_NUMBER } = valuesConstants; const columns: TableColumn[] = [ { name: 'paymentRelation', - title: 'Соотношение платежа', + title: '% платежа', Component: InputNumber, props: { min: '0.01', @@ -124,8 +124,10 @@ const callbacks: TableColumnCallbacks = { }; const features: TableColumnFeatures = { - numerize: { - columnTitle: 'Номер платежа', + numerize: true, + split: { + rowsNumber: 12, + columnsNumber: 3, }, }; diff --git a/src/client/Containers/Calculation/lib/elements/tables/results.ts b/src/client/Containers/Calculation/lib/elements/tables/results.ts index 2a55ced..0a05714 100644 --- a/src/client/Containers/Calculation/lib/elements/tables/results.ts +++ b/src/client/Containers/Calculation/lib/elements/tables/results.ts @@ -37,9 +37,7 @@ const columns: TableColumn[] = [ ]; const features: TableColumnFeatures = { - numerize: { - columnTitle: 'Номер', - }, + numerize: true, }; const params = { features }; diff --git a/src/client/Containers/Calculation/lib/elements/titles.ts b/src/client/Containers/Calculation/lib/elements/titles.ts index 7b80dd1..679814b 100644 --- a/src/client/Containers/Calculation/lib/elements/titles.ts +++ b/src/client/Containers/Calculation/lib/elements/titles.ts @@ -136,6 +136,9 @@ export const elementsTitles: TElements = { tbxINNForCalc: 'ИНН контрагента', selectLegalClientRegion: 'Регион по юр.адресу клиента', selectLegalClientTown: 'Город по юр.адресу клиента', + selectSubsidy: 'Субсидия', + labelSubsidySum: 'Сумма субсидии с НДС', + selectFuelCard: 'Топливная карта', }; const resultsTitles: TElements = { diff --git a/src/client/Containers/Calculation/lib/elements/values.ts b/src/client/Containers/Calculation/lib/elements/values.ts index bde3df9..c7e88fc 100644 --- a/src/client/Containers/Calculation/lib/elements/values.ts +++ b/src/client/Containers/Calculation/lib/elements/values.ts @@ -135,6 +135,9 @@ export const elementsValues: TElements = { radioTypePTS: 'typePTS', selectLegalClientRegion: 'legalClientRegion', selectLegalClientTown: 'legalClientTown', + selectSubsidy: 'subsidy', + labelSubsidySum: 'subsidySum', + selectFuelCard: 'fuelCard', }; const resultElementsValues: TElements = { diff --git a/src/client/Containers/Calculation/lib/fetchData/index.js b/src/client/Containers/Calculation/lib/fetchData/index.js index d2aa985..048a940 100644 --- a/src/client/Containers/Calculation/lib/fetchData/index.js +++ b/src/client/Containers/Calculation/lib/fetchData/index.js @@ -1,6 +1,9 @@ import CalculationStore from 'client/stores/CalculationStore'; +import initialOptions from 'client/stores/CalculationStore/config/initialOptions'; +import initialValues from 'client/stores/CalculationStore/config/initialValues'; import UserStore from 'client/stores/UserStore'; import CrmService from 'core/services/CrmService'; +import { Process } from 'core/types/Calculation/Store/process'; import getUser from './getUser'; import insuranceQuery from './queries/insuranceQuery'; import optionsQuery from './queries/optionsQuery'; @@ -12,7 +15,8 @@ export default () => new Promise(async (resolve, reject) => { await getUser(); const domainname = UserStore.getDomainName(); - + const { calculationProcess } = CalculationStore.stores; + calculationProcess.addProcess(Process.Init); Promise.all([ CrmService.crmgqlquery({ ...initialOwnerQuery, @@ -32,7 +36,7 @@ export default () => .then( ([ { entities: ownerOptions }, - { entities: initialOptions }, + { entities: options }, { entities: staticEntities }, { entities: { systemuser }, @@ -41,10 +45,16 @@ export default () => entities: { insuranceCompany }, }, ]) => { - CalculationStore.applyOptions(ownerOptions); - CalculationStore.applyOptions(initialOptions); - CalculationStore.applyStaticData(staticEntities); - CalculationStore.applyStaticData({ systemuser: [systemuser] }); + CalculationStore.applyOptions({ + ...initialOptions, + ...ownerOptions, + ...options, + }); + CalculationStore.applyStaticData({ + ...staticEntities, + systemuser: [systemuser], + }); + CalculationStore.setValues(initialValues, true); CalculationStore.setTableColumns('tableInsurance')({ options: { insuranceCompany }, }); @@ -79,6 +89,8 @@ export default () => ); } + calculationProcess.deleteProcess(Process.Init); + resolve(); }, ) diff --git a/src/client/Containers/Calculation/lib/fetchData/queries/insuranceQuery.ts b/src/client/Containers/Calculation/lib/fetchData/queries/insuranceQuery.ts index e09080c..7617e32 100644 --- a/src/client/Containers/Calculation/lib/fetchData/queries/insuranceQuery.ts +++ b/src/client/Containers/Calculation/lib/fetchData/queries/insuranceQuery.ts @@ -11,7 +11,9 @@ const query = gql` name evo_type_ins_policy evo_id_elt + evo_id_elt_smr evo_id_elt_osago + evo_legal_region_calc } } `; diff --git a/src/client/Containers/Calculation/lib/fetchData/queries/optionsQuery.ts b/src/client/Containers/Calculation/lib/fetchData/queries/optionsQuery.ts index 14fc964..5e67126 100644 --- a/src/client/Containers/Calculation/lib/fetchData/queries/optionsQuery.ts +++ b/src/client/Containers/Calculation/lib/fetchData/queries/optionsQuery.ts @@ -16,6 +16,7 @@ const query = gql` $nsib_product_type: Int $tracker_product_type: Int $telematic_product_type: Int + $fuelcard_product_type: Int $techcard_product_type: Int ) { selectSupplier: accounts( @@ -80,6 +81,7 @@ const query = gql` evo_id evo_name evo_brandid + evo_brand_owner evo_importer_reward_perc evo_importer_reward_rub evo_vehicle_type @@ -248,12 +250,14 @@ const query = gql` evo_id evo_leasingobject_typeid } + evo_delivery_time } selectRate: evo_rates( statecode: $statecode - ) # evo_datefrom_param: { lte: $currentDate } - # evo_dateto_param: { gte: $currentDate } - { + evo_datefrom_param: { lte: $currentDate } + evo_dateto_param: { gte: $currentDate } + ) { + createdon evo_id evo_rateid evo_name @@ -267,6 +271,7 @@ const query = gql` evo_tarifid evo_name } + evo_credit_period } selectLeaseObjectType: evo_leasingobject_types(statecode: $statecode) { evo_name @@ -292,6 +297,53 @@ const query = gql` accountid } } + selectSubsidy: evo_subsidies( + statecode: $statecode + evo_datefrom_param: { lte: $currentDate } + evo_dateto_param: { gte: $currentDate } + ) { + evo_name + evo_subsidyid + evo_percent_subsidy + evo_subsidy_summ + evo_max_subsidy_summ + evo_get_subsidy_payment + evo_brands { + evo_brandid + } + evo_models { + evo_modelid + } + evo_leasingobject_types { + evo_leasingobject_typeid + } + accounts { + accountid + } + } + selectFuelCard: evo_addproduct_types( + statecode: $statecode + evo_product_type: $fuelcard_product_type + evo_datefrom_param: { lte: $currentDate } + evo_dateto_param: { gte: $currentDate } + ) { + evo_id + evo_name + evo_addproduct_typeid + evo_accountid + evo_graph_price_withoutnds + evo_cost_service_provider_withoutnds + evo_retro_bonus_withoutnds + evo_prime_cost + evo_graph_price + evo_max_period + evo_min_period + evo_controls_program + evo_helpcard_type + evo_leasingobject_types { + evo_leasingobject_typeid + } + } } `; @@ -309,6 +361,7 @@ const variables = { tracker_product_type: 100000003, telematic_product_type: 100000004, techcard_product_type: 100000000, + fuelcard_product_type: 100000005, }; const toOptions = [ @@ -332,6 +385,8 @@ const toOptions = [ 'selectLeaseObjectType', 'selectObjectRegionRegistration', 'selectLegalClientRegion', + 'selectSubsidy', + 'selectFuelCard', ]; export default { diff --git a/src/client/Containers/Calculation/lib/fetchData/queries/ownerQuery.ts b/src/client/Containers/Calculation/lib/fetchData/queries/ownerQuery.ts index 0f94ffc..6dc981a 100644 --- a/src/client/Containers/Calculation/lib/fetchData/queries/ownerQuery.ts +++ b/src/client/Containers/Calculation/lib/fetchData/queries/ownerQuery.ts @@ -19,6 +19,7 @@ const query = gql` } } evo_inn + link } selectOpportunity: opportunities( statecode: $statecode @@ -37,6 +38,7 @@ const query = gql` evo_city_fias_id } } + link } } `; diff --git a/src/client/Containers/Calculation/lib/fetchData/queries/staticDataQuery.ts b/src/client/Containers/Calculation/lib/fetchData/queries/staticDataQuery.ts index 19b5dfb..cb3a6c4 100644 --- a/src/client/Containers/Calculation/lib/fetchData/queries/staticDataQuery.ts +++ b/src/client/Containers/Calculation/lib/fetchData/queries/staticDataQuery.ts @@ -56,6 +56,15 @@ const query = gql` evo_name evo_job_titleid } + evo_addproduct_type: evo_addproduct_types( + statecode: $statecode + evo_datefrom_param: { lte: $currentDate } + evo_dateto_param: { gte: $currentDate } + ) { + evo_product_type + evo_addproduct_typeid + evo_controls_program + } } `; diff --git a/src/client/Containers/Calculation/lib/renderSections.js b/src/client/Containers/Calculation/lib/renderSections.js index 80efe0b..b6c8834 100644 --- a/src/client/Containers/Calculation/lib/renderSections.js +++ b/src/client/Containers/Calculation/lib/renderSections.js @@ -1,11 +1,9 @@ import { Tabs } from 'antd'; import Divider from 'client/Elements/Divider'; import { SecondaryColoredText } from 'client/Elements/Text'; -import Tooltip from 'client/Elements/Tooltip'; import colors from 'client/UIKit/colors'; import { Box, Flex } from 'client/UIKit/grid'; import mq from 'client/UIKit/mq'; -import { Fragment } from 'react'; import styled from 'styled-components'; import { buildElement } from '../lib/buildElement'; import elementsProps from './elements/elementsProps'; @@ -19,51 +17,74 @@ const ElementTitle = styled.h5` margin: 0 8px 3px 0; text-overflow: ellipsis; overflow: hidden; - white-space: nowrap; + white-space: ${props => props.whiteSpace || 'nowrap'}; `; -const renderElements = ({ elements }) => { +const Head = ({ sub, elementTitle, style }) => { + if (sub?.Component) { + return ( + + {elementTitle} + + + ); + } + return {elementTitle}; +}; + +const renderElements = ({ elements, elementStyle }) => { return elements.map((elementName, ie) => { const elementTitle = elementsTitles[elementName]; - const { tooltip, tag, ...elementProps } = elementsProps[elementName] || {}; - - let TagComponent = () => null; - if (tag && tag.Component) { - TagComponent = tag.Component; - } + const { tooltip, sub, ...elementProps } = elementsProps[elementName] || {}; const Component = buildElement(elementName, elementProps); - return ( - - - - {elementTitle} - - - - - + const Tooltip = tooltip?.Component; + + const element = ( + + + + ); + if (tooltip) { + return {element}; + } + return element; }); }; +const ElementsGrid = styled(Box)` + display: grid; + grid-gap: 10px; + + grid-template-columns: 1fr; + ${mq.laptop` + grid-template-columns: repeat(${props => + props.columnsNumber || props.defaultColumnsNumber}, 1fr); + `} +`; + const renderBlocks = ({ blocks }) => { if (!blocks || blocks.length === 0) { return null; } return blocks.map((block, ib) => { - const { elements, title } = block; + const { elements, title, style, elementStyle } = block; return ( - - - {title && {title}} - {renderElements({ elements })} - - + + {title && {title}} + + {renderElements({ elements, elementStyle })} + + ); }); }; @@ -74,17 +95,6 @@ const BlocksTitle = styled(Divider)` font-size: 0.95rem; `; -const BlocksGrid = styled(Box)` - display: grid; - grid-gap: 10px; - - grid-template-columns: 1fr; - ${mq.laptop` - grid-template-columns: repeat(${props => - props.columnsNumber || 2}, 1fr); - `} -`; - export const renderGroups = ({ groups }) => { if (!groups || groups.length === 0) { return null; @@ -95,7 +105,9 @@ export const renderGroups = ({ groups }) => { return ( {title && {title}} - {renderBlocks({ blocks })} + + {renderBlocks({ blocks })} + ); }); @@ -103,7 +115,7 @@ export const renderGroups = ({ groups }) => { export const renderSections = ({ sectionsList }) => { return ( - + {sectionsList.map((section, is) => { const { title, groups } = section; return ( diff --git a/src/client/Elements/Download.jsx b/src/client/Elements/Link.jsx similarity index 75% rename from src/client/Elements/Download.jsx rename to src/client/Elements/Link.jsx index 82706a8..a3a17db 100644 --- a/src/client/Elements/Download.jsx +++ b/src/client/Elements/Link.jsx @@ -1,7 +1,7 @@ import { Button as AntButton } from 'antd'; import { ElementStatus } from 'core/types/statuses'; -const Download = ({ status, url, text, icon: Icon, ...props }) => { +const Link = ({ status, url, text, icon: Icon, ...props }) => { return ( { href={url} disabled={status === ElementStatus.Disabled || !url} loading={status === ElementStatus.Loading} - icon={} + icon={Icon && } > {text} ); }; -export default Download; +export default Link; diff --git a/src/client/Elements/Table.jsx b/src/client/Elements/Table.jsx index 446e347..b8991c2 100644 --- a/src/client/Elements/Table.jsx +++ b/src/client/Elements/Table.jsx @@ -1,13 +1,16 @@ import colors from 'client/UIKit/colors'; import { Box } from 'client/UIKit/grid'; import mq from 'client/UIKit/mq'; +import { pick } from 'lodash'; +import { toJS } from 'mobx'; +import { useMemo } from 'react'; import styled from 'styled-components'; -const TableWrapper = styled(Box)` +const TableStyles = styled(Box)` overflow-x: auto; table { + width: 100%; ${mq.laptop` - width: 100%; overflow-x: none; `} table-layout: fixed; @@ -59,56 +62,130 @@ const TableWrapper = styled(Box)` } `; +const TablesGrid = styled(Box)` + display: ${props => props.split && 'grid'}; + grid-template-columns: 1fr; + ${mq.laptop` + grid-gap: 10px; + grid-template-columns: repeat(${props => + props?.split?.columnsNumber || '2'}, 1fr); + `} +`; + +function buildHead(features, columns) { + return () => ( + + + {features?.numerize && {features.numerize.columnTitle || '#'}} + {columns.map(column => ( + {column.title} + ))} + + + ); +} + +function buildBody( + tableName, + features, + rows, + columnsProps, + withTableValue, + partNumber, + rowsNumber, +) { + return () => ( + + {rows.map((row, rowIndex) => { + const partRowIndex = rowIndex + partNumber * rowsNumber; + return ( + + {features?.numerize && {partRowIndex + 1}} + {Object.keys(row).map(propName => { + const CellComponent = columnsProps[propName].Component; + const Cell = withTableValue(CellComponent)({ + tableName, + rowIndex: partRowIndex, + propName, + ...columnsProps[propName].props, + }); + return ( + + + + ); + })} + + ); + })} + + ); +} + +const useColumnsProps = columns => + useMemo( + () => + columns.reduce((acc, col) => { + acc[col.name] = pick(col, ['Component', 'props']); + return acc; + }, {}), + [columns], + ); + +const useSplit = (split, rows) => { + return useMemo(() => { + if (!split || !rows?.length) { + return { + partsNumber: 1, + }; + } + const { rowsNumber } = split; + return { partsNumber: Math.ceil(rows?.length / rowsNumber), rowsNumber }; + }, [rows?.length]); +}; + const Table = ({ name: tableName, - columns, rows, + columns, params: { features }, withTableValue, }) => { - return ( - - - - - {features && features.numerize && ( - - )} - {columns.map(({ title }, ci) => { - return ; - })} - - - - {rows.map((row, ri) => { - const rowProps = Object.keys(row); - return ( - - {features && features.numerize && } - {rowProps.map((rowPropName, ki) => { - const columnIndex = columns.findIndex( - c => c.name === rowPropName, - ); - const { Component } = columns[columnIndex]; - const Element = withTableValue(Component)({ - tableName, - rowIndex: ri, - propName: rowPropName, - ...columns[columnIndex].props, - }); - return ( - - ); - })} - - ); - })} - -
{features.numerize.columnTitle || '#'}{title}
{ri + 1} - -
-
- ); + const split = useSplit(features?.split, rows); + const rowsNumber = features?.split?.rowsNumber || rows?.length; + const columnsProps = useColumnsProps(columns); + + const Head = buildHead(features, columns); + const tables = useMemo(() => { + let tables = []; + for (const partNumber of Array.from(Array(split.partsNumber).keys())) { + const a = 0 + rowsNumber * partNumber; + const b = rowsNumber + rowsNumber * partNumber; + + const rowsPart = toJS(rows).slice(a, b); + + const Body = buildBody( + tableName, + features, + rowsPart, + columnsProps, + withTableValue, + partNumber, + rowsNumber, + ); + tables.push( + + + + +
+
, + ); + } + return tables; + }, [rows.length]); + + return {tables}; }; export default Table; diff --git a/src/client/Elements/Tooltip.jsx b/src/client/Elements/Tooltip.jsx index 724d116..1e48026 100644 --- a/src/client/Elements/Tooltip.jsx +++ b/src/client/Elements/Tooltip.jsx @@ -1,3 +1,5 @@ import { Tooltip as AntTooltip } from 'antd'; -export default AntTooltip; +export default params => props => ( + {props.children} +); diff --git a/src/client/hocs/Calculation/withTable.jsx b/src/client/hocs/Calculation/withTable.jsx index a149a56..43298fc 100644 --- a/src/client/hocs/Calculation/withTable.jsx +++ b/src/client/hocs/Calculation/withTable.jsx @@ -31,7 +31,7 @@ const withTableValue = callbacks => Component => ({ tableName, rowIndex, propName, - columnCallback: callbacks && callbacks[propName], + columnCallback: callbacks?.[propName], }); const { status } = useTableStatus({ tableName, rowIndex, propName }); const { validateStatus, message } = useTableValidation({ diff --git a/src/client/hooks/Calculation/useFetch.js b/src/client/hooks/Calculation/useFetch.js index 2a030b6..23d86dc 100644 --- a/src/client/hooks/Calculation/useFetch.js +++ b/src/client/hooks/Calculation/useFetch.js @@ -5,7 +5,9 @@ export const useFetch = ({ fetchData }) => { const [error, setError] = useState(); const [isLoading, setIsLoading] = useState(false); - useEffect(() => { + function fetch() { + setError(false); + setResponse(undefined); setIsLoading(true); fetchData() .then(res => { @@ -17,6 +19,10 @@ export const useFetch = ({ fetchData }) => { .finally(() => { setIsLoading(false); }); + } + + useEffect(() => { + fetch(); }, []); - return { response, isLoading, error }; + return { response, isLoading, error, fetch }; }; diff --git a/src/client/hooks/Calculation/useOptions.js b/src/client/hooks/Calculation/useOptions.js index 65d52b4..7a7097e 100644 --- a/src/client/hooks/Calculation/useOptions.js +++ b/src/client/hooks/Calculation/useOptions.js @@ -2,8 +2,8 @@ import { useStores } from '../useStores'; export const useOptions = elementName => { const { calculationStore } = useStores(); - const options = calculationStore.options[elementName] || []; - const filter = calculationStore.filters[elementName]; + const options = calculationStore?.options?.[elementName] || []; + const filter = calculationStore?.filters?.[elementName]; return { options: filter ? filter(options) : options, @@ -13,11 +13,9 @@ export const useOptions = elementName => { export const useTableOptions = ({ tableName, rowIndex, propName }) => { const { calculationStore } = useStores(); const options = - (calculationStore.tables[tableName].options && - calculationStore.tables[tableName].options[propName]) || - []; + calculationStore?.tables?.[tableName]?.options?.[propName] || []; const filter = - calculationStore.tables[tableName].rows[rowIndex][propName].filter; + calculationStore?.tables?.[tableName]?.rows?.[rowIndex]?.[propName]?.filter; return { options: filter ? filter(options) : options, diff --git a/src/client/hooks/Calculation/useValidation.ts b/src/client/hooks/Calculation/useValidation.ts index f13f444..18bd7cc 100644 --- a/src/client/hooks/Calculation/useValidation.ts +++ b/src/client/hooks/Calculation/useValidation.ts @@ -91,7 +91,8 @@ export const useTableValidation = ({ const { calculationStore } = useStores(); const validationStatus = - calculationStore.tables[tableName].rows[rowIndex][propName]?.validation; + calculationStore?.tables?.[tableName]?.rows?.[rowIndex]?.[propName] + ?.validation; useEffect(() => { setValidation(validationStatus); }, [validationStatus]); diff --git a/src/client/hooks/Calculation/useValue.js b/src/client/hooks/Calculation/useValue.js index 82fe3b1..7beecf8 100644 --- a/src/client/hooks/Calculation/useValue.js +++ b/src/client/hooks/Calculation/useValue.js @@ -44,8 +44,8 @@ export const useTableValue = ({ const [currentValue, setCurrentValue] = useState(undefined); //get row value from store - const targetTable = calculationStore.tables[tableName]; - const sourceValue = targetTable.rows[rowIndex][propName].value; + const targetTable = calculationStore?.tables?.[tableName]; + const sourceValue = targetTable?.rows?.[rowIndex]?.[propName]?.value; useEffect(() => { if (sourceValue !== undefined) { setCurrentValue(sourceValue); diff --git a/src/client/stores/CalculationStore/Data/tables.js b/src/client/stores/CalculationStore/Data/tables.js index 2f51fc6..cc879a3 100644 --- a/src/client/stores/CalculationStore/Data/tables.js +++ b/src/client/stores/CalculationStore/Data/tables.js @@ -12,7 +12,10 @@ const tablesActions = { getTableRowValues(tableName, rowIndex, paramName) { let values = {}; - const row = this.tables[tableName].rows[rowIndex]; + const row = this?.tables?.[tableName]?.rows?.[rowIndex]; + if (!row) { + return values; + } const keys = Object.keys(row); let overridedValue; @@ -41,7 +44,7 @@ const tablesActions = { setTableRows(tableName, startIndex, override) { return rows => { - if (this.tables[tableName] && this.tables[tableName].rows) + if (this?.tables[tableName]?.rows) for ( let i = startIndex, j = 0; i < startIndex + rows.length; diff --git a/src/client/stores/CalculationStore/Data/values.js b/src/client/stores/CalculationStore/Data/values.js index 7a8903d..9cdaa9f 100644 --- a/src/client/stores/CalculationStore/Data/values.js +++ b/src/client/stores/CalculationStore/Data/values.js @@ -1,15 +1,15 @@ import { getValueName } from 'client/Containers/Calculation/lib/elements/tools'; -import initialFilters from 'client/stores/CalculationStore/config/initialFilters'; -import initialOptions from 'client/stores/CalculationStore/config/initialOptions'; +import initialFilters, { + noResetValueElements, +} from 'client/stores/CalculationStore/config/initialFilters'; import initialStatuses from 'client/stores/CalculationStore/config/initialStatuses'; -import initialValues from 'client/stores/CalculationStore/config/initialValues'; import { isNil, mergeWith, pick } from 'lodash'; const valuesData = { - values: initialValues, + values: {}, statuses: initialStatuses, validations: {}, - options: initialOptions, + options: {}, filters: initialFilters, }; @@ -23,8 +23,9 @@ const valuesActions = { setValue(sourceValueName, newValue) { this.values[sourceValueName] = newValue; }, - setValues(values) { - this.values = values; + setValues(values, override) { + if (override) this.values = values; + this.values = Object.assign(this.values, values); }, getStatus(elementName) { @@ -40,6 +41,11 @@ const valuesActions = { this.statuses[elementName] = status; }, + setStatuses(statuses, override) { + if (override) this.statuses = statuses; + this.statuses = Object.assign(this.statuses, statuses); + }, + getValidation(elementName) { return this.validations[elementName]; }, @@ -102,7 +108,8 @@ const valuesActions = { const value = this.getValue(valueName); if ( filter && - !filter(this.getOptions(elementName)).some(x => x.value === value) + !filter(this.getOptions(elementName)).some(x => x.value === value) && + !noResetValueElements.includes(elementName) ) { this.setValue(valueName, null); } diff --git a/src/client/stores/CalculationStore/Effects/actions/calculate/prepareData.ts b/src/client/stores/CalculationStore/Effects/actions/calculate/prepareData.ts index 5435402..75d593a 100644 --- a/src/client/stores/CalculationStore/Effects/actions/calculate/prepareData.ts +++ b/src/client/stores/CalculationStore/Effects/actions/calculate/prepareData.ts @@ -89,7 +89,7 @@ export default function (this: ICalculationStore): IPreparedData { preparedValues.calcType = values.calcType; preparedValues.irrExpected = (values.IRR_Perc as number) / 100; preparedValues.npvniExpected = 0; - preparedValues.totalExpected = values.totalPayments; + preparedValues.totalExpected = values.totalPayments + values.subsidySum; preparedValues.nmper = values.leasingPeriod; preparedValues.leasing0K = values.product === 'LEASING0' @@ -97,6 +97,9 @@ export default function (this: ICalculationStore): IPreparedData { (0.0234 / ((1 - 1 / 1.0234) ^ ((preparedValues.nmper as number) - 2))) : 1; preparedValues.loanRate = parseFloat(values.creditRate) / 100; + preparedValues.loanRatePeriod = this.getOption( + 'selectRate', + )?.evo_credit_period; preparedValues.balanceHolder = values.balanceHolder; preparedValues.dogDate = preparedValues.calcDate; preparedValues.paymentDateNew = undefined; @@ -107,6 +110,14 @@ export default function (this: ICalculationStore): IPreparedData { preparedValues.lastPayment = (values.lastPaymentPerc as number) / 100; preparedValues.lastPaymentSum = (values.lastPaymentRub as number) / (1 + valuesConstants.VAT); + preparedValues.subsidySum = + parseInt(values.subsidySum) / (1 + valuesConstants.VAT); + preparedValues.subsidyPaymentNumber = this.getOption( + 'selectSubsidy', + )?.evo_get_subsidy_payment; + preparedValues.fuelCardSum = this.getOption( + 'selectFuelCard', + )?.evo_graph_price_withoutnds; preparedValues.scheduleOfPayments = values.graphType; preparedValues.comissionRub = (values.comissionRub as number) / (1 + valuesConstants.VAT); @@ -426,6 +437,8 @@ export default function (this: ICalculationStore): IPreparedData { preparedValues.tLMCost = telematic.evo_graph_price_withoutnds || 0; } + // + const nsibBaseValue = ((preparedValues.plPrice || 0) + (preparedValues.insuranceContract + @@ -512,6 +525,50 @@ export default function (this: ICalculationStore): IPreparedData { } } + if ( + evo_coefficient_bonuses && + evo_coefficient_bonuses.length > 0 && + systemuser + ) { + const evo_sot_coefficient_type = this.getStaticData( + 'evo_sot_coefficient_type', + ).find(x => x.evo_id === 'DIRECTOR_BONUS_NSIB'); + + const evo_coefficient = evo_coefficient_bonuses.find( + x => + x.evo_sot_coefficient_typeid === + evo_sot_coefficient_type?.evo_sot_coefficient_typeid, + ); + + if (evo_coefficient) { + preparedValues.directorBonusNsib = + (evo_coefficient.evo_sot_coefficient || 0) * + (preparedValues.nsibBrutto || 0); + } + } + + if ( + evo_coefficient_bonuses && + evo_coefficient_bonuses.length > 0 && + systemuser + ) { + const evo_sot_coefficient_type = this.getStaticData( + 'evo_sot_coefficient_type', + ).find(x => x.evo_id === 'REGIONAL_DIRECTOR_BONUS_NSIB'); + + const evo_coefficient = evo_coefficient_bonuses.find( + x => + x.evo_sot_coefficient_typeid === + evo_sot_coefficient_type?.evo_sot_coefficient_typeid, + ); + + if (evo_coefficient) { + preparedValues.regionalDirectorBonusNsib = + (evo_coefficient.evo_sot_coefficient || 0) * + (preparedValues.nsibBrutto || 0); + } + } + if ( evo_coefficient_bonuses && evo_coefficient_bonuses.length > 0 && diff --git a/src/client/stores/CalculationStore/Effects/actions/calculate/results.ts b/src/client/stores/CalculationStore/Effects/actions/calculate/results.ts index 112f565..a70f485 100644 --- a/src/client/stores/CalculationStore/Effects/actions/calculate/results.ts +++ b/src/client/stores/CalculationStore/Effects/actions/calculate/results.ts @@ -15,15 +15,30 @@ export default { const results: TableProps[] = []; for (let i = 0; i < preparedData.preparedValues.nmper; i++) { + const balanceHolder = this.getValue('balanceHolder'); + let redemptionAmount = { + value: sumRepaymentColumn?.values[i + 1], + }; + if (balanceHolder === 100000001 && i < 12) { + redemptionAmount = { + value: 0, + }; + } + results.push({ paymentSum: { value: sumWithVatColumn?.values[i + 1] }, ndsCompensation: { value: vatColumn?.values[i + 1] }, - redemptionAmount: { - value: sumRepaymentColumn?.values[i + 1], - }, + redemptionAmount, }); } - //TODO: speed up table render + + const subdidySum = this.getValue('subsidySum') || 0; + if (results[0]?.paymentSum?.value) + results[0].paymentSum.value -= subdidySum; + if (results[0]?.ndsCompensation?.value) { + results[0].ndsCompensation.value -= subdidySum - subdidySum / 1.2; + } + this.setTableRows('tableResults', 0)(results); } }, @@ -33,7 +48,10 @@ export default { res: IGetCalculationResponse, ) { const { sumWithVatColumn } = res.columns; - this.setValue('resultTotalGraphwithNDS', sumWithVatColumn?.values[0] || 0); + this.setValue( + 'resultTotalGraphwithNDS', + (sumWithVatColumn?.values[0] || 0) - (this.getValue('subsidySum') || 0), + ); this.setValue( 'resultPlPrice', (preparedData?.preparedValues?.acceptSum || 0) * @@ -74,7 +92,8 @@ export default { this.setValue( 'resultFirstPayment', (preparedData?.preparedValues?.firstPaymentSum || 0) * - (1 + valuesConstants.VAT), + (1 + valuesConstants.VAT) - + this.getValue('subsidySum') || 0, ); this.setValue( 'resultLastPayment', @@ -133,7 +152,8 @@ export default { ); this.setValue( 'totalPayments', - res?.columns?.sumWithVatColumn?.values[0] || 0, + (res?.columns?.sumWithVatColumn?.values[0] || 0) - + (this.getValue('subsidySum') || 0), ); }, }; diff --git a/src/client/stores/CalculationStore/Effects/actions/calculate/validate/elements.ts b/src/client/stores/CalculationStore/Effects/actions/calculate/validate/elements.ts index eb0535c..34475c8 100644 --- a/src/client/stores/CalculationStore/Effects/actions/calculate/validate/elements.ts +++ b/src/client/stores/CalculationStore/Effects/actions/calculate/validate/elements.ts @@ -1,3 +1,4 @@ +import { getValueName } from 'client/Containers/Calculation/lib/elements/tools'; import { pipe } from 'core/tools/func'; import { ICalculationStore } from 'core/types/Calculation/Store'; import { @@ -8,9 +9,11 @@ import CONDITIONS from 'core/validation/conditions'; import { convertToValidationResult, getValue, + showValidationMessages, validate, ValidationCondition, } from 'core/validation/validate'; +import { isNil } from 'lodash'; const customConditions: TElements = { selectLeaseObjectCategory: calculationStore => { @@ -78,6 +81,105 @@ const customConditions: TElements = { } return { isValid: true }; }, + radioRequirementTelematic: calculationStore => { + const { + telematic, + tracker, + requirementTelematic, + } = calculationStore.getValues([ + 'telematic', + 'tracker', + 'requirementTelematic', + ]); + + if (requirementTelematic !== 100000004 && !telematic && !tracker) { + return { + isValid: false, + message: 'Не указан Тип средства контроля: (Маяк или Телематика)', + }; + } + if (requirementTelematic === 100000004 && (telematic || tracker)) { + return { + isValid: false, + message: 'Маяк и телематика не должны быть указаны', + }; + } + return { isValid: true }; + }, + selectTownRegistration: calculationStore => { + const { + townRegistration, + objectRegistration, + } = calculationStore.getValues(['townRegistration', 'objectRegistration']); + if (objectRegistration === 100000000 && !townRegistration) { + return { + isValid: false, + }; + } + return { + isValid: true, + }; + }, + tbxFirstPaymentRub: calculationStore => { + const { firstPaymentRub, subsidySum } = calculationStore.values; + return { + isValid: firstPaymentRub - subsidySum > 0, + message: + 'Первый платеж с учетом субсидии получается отрицательный, увеличьте первый платеж', + }; + }, + // TODO: temp (move to tableInsurance validation) + tbxLeasingPeriod: calculationStore => { + const { recalcWithRevision, leasingPeriod } = calculationStore.values; + const quote = calculationStore.getOption('selectQuote'); + const kaskoRowIndex = calculationStore.tables.tableInsurance.rows.findIndex( + x => x.policyType?.value === 'КАСКО', + ); + + const kaskoValues = calculationStore.getTableRowValues( + 'tableInsurance', + kaskoRowIndex, + 'value', + ); + + const kaskoInsTerm = kaskoValues.insTerm; + + if ( + recalcWithRevision && + quote?.evo_one_year_insurance && + leasingPeriod > 16 && + kaskoInsTerm !== 100000000 + ) { + calculationStore.setTableRow( + 'tableInsurance', + kaskoRowIndex, + false, + )({ + insTerm: { + validation: false, + }, + }); + return { + isValid: false, + message: + 'Невозможно включить страховку на весь срок для однолетнего полиса', + }; + } else { + calculationStore.setTableRow( + 'tableInsurance', + kaskoRowIndex, + false, + )({ + insTerm: { + validation: true, + }, + }); + + return { + isValid: true, + }; + } + }, }; const elementsValidations: TElements = { @@ -91,7 +193,6 @@ const elementsValidations: TElements = { selectDealer: CONDITIONS.IS_NULL, selectDealerPerson: CONDITIONS.IS_NULL, selectRegionRegistration: CONDITIONS.IS_NULL, - selectTownRegistration: CONDITIONS.IS_NULL, selectTarif: CONDITIONS.IS_NULL, // selectRate: VALIDATIONS.IS_NULL, selectRegistration: CONDITIONS.IS_NULL, @@ -117,7 +218,32 @@ const elementsConditions = (Object.keys( {}, ); -const conditions = Object.assign({}, customConditions, elementsConditions); +const entityElementsConditions = ([ + 'selectIndAgentRewardCondition', + 'selectCalcBrokerRewardCondition', + 'selectFinDepartmentRewardCondtion', +] as ElementsNames[]).reduce( + (ac: TElements, elementName) => { + const valueName = getValueName(elementName); + ac[elementName] = (calculationStore, elementName) => { + if (isNil(calculationStore.getValue(valueName))) { + return { isValid: true }; + } + return { + isValid: calculationStore.getOption(elementName) !== undefined, + }; + }; + return ac; + }, + {}, +); + +const conditions = Object.assign( + {}, + customConditions, + elementsConditions, + entityElementsConditions, +); export default function (this: ICalculationStore) { const validationResult = validate(this, conditions); @@ -125,4 +251,5 @@ export default function (this: ICalculationStore) { const isValid = validationResult[elementName]?.isValid; if (isValid !== undefined) this.setValidation(elementName, isValid); }); + showValidationMessages(validationResult, 'Ошибка во время расчета графика'); } diff --git a/src/client/stores/CalculationStore/Effects/autorun.ts b/src/client/stores/CalculationStore/Effects/autorun.ts index 2a244f7..0767a80 100644 --- a/src/client/stores/CalculationStore/Effects/autorun.ts +++ b/src/client/stores/CalculationStore/Effects/autorun.ts @@ -1,6 +1,7 @@ import { openNotification } from 'client/Elements/Notification'; import { IAutorunEffect } from 'core/types/Calculation/Store/effect'; import { ElementStatus } from 'core/types/statuses'; +import { convertPrice } from './lib/tools'; const autorunEffects: IAutorunEffect[] = [ calculationStore => () => { @@ -106,34 +107,7 @@ const autorunEffects: IAutorunEffect[] = [ // } else { // calculationStore.setValidation('tbxCountSeats', true); // } - // }, - calculationStore => () => { - const { requirementTelematic } = calculationStore.values; - if (requirementTelematic) { - const tracker = calculationStore.options.selectTracker?.find(x => - x.evo_controls_program?.includes(requirementTelematic), - ); - if (tracker) - calculationStore.setValue('tracker', tracker.evo_addproduct_typeid); - else { - calculationStore.setValue('tracker', null); - } - } - }, - - calculationStore => () => { - const { requirementTelematic } = calculationStore.values; - if (requirementTelematic) { - const telematic = calculationStore.options.selectTelematic?.find(x => - x.evo_controls_program?.includes(requirementTelematic), - ); - if (telematic) - calculationStore.setValue('telematic', telematic.evo_addproduct_typeid); - else { - calculationStore.setValue('telematic', null); - } - } - }, + // // }, calculationStore => () => { const { leaseObjectType: leaseObjectTypeId } = calculationStore.values; @@ -213,6 +187,48 @@ const autorunEffects: IAutorunEffect[] = [ } } }, + + calculationStore => () => { + const subsidy = calculationStore.getOption('selectSubsidy'); + if (subsidy?.evo_subsidy_summ && subsidy?.evo_subsidy_summ > 0) { + calculationStore.setValue('subsidySum', subsidy?.evo_subsidy_summ); + } else { + if (subsidy?.evo_max_subsidy_summ) { + const { + leaseObjectPrice, + supplierDiscountRub, + } = calculationStore.values; + const supplierCurrency = calculationStore.getOption( + 'selectSupplierCurrency', + ); + const evo_currencychanges = calculationStore.getStaticData( + 'evo_currencychange', + ); + const evo_currencychange = evo_currencychanges.find( + x => + x.evo_ref_transactioncurrency === + supplierCurrency?.transactioncurrencyid, + ); + const plPriceRub = convertPrice( + supplierCurrency?.isocurrencycode, + leaseObjectPrice - supplierDiscountRub, + evo_currencychange?.evo_currencychange, + ); + + const subsidySum = + (plPriceRub * (subsidy?.evo_percent_subsidy || 0)) / 100; + + const subsidySumValue = + subsidySum > subsidy?.evo_max_subsidy_summ + ? subsidy?.evo_max_subsidy_summ + : subsidySum; + + calculationStore.setValue('subsidySum', subsidySumValue); + } else { + calculationStore.setValue('subsidySum', 0); + } + } + }, ]; export default autorunEffects; diff --git a/src/client/stores/CalculationStore/Effects/computed.js b/src/client/stores/CalculationStore/Effects/computed.js deleted file mode 100644 index b87e7ea..0000000 --- a/src/client/stores/CalculationStore/Effects/computed.js +++ /dev/null @@ -1,66 +0,0 @@ -import customValues from './lib/customValues'; - -const LEASE_OBJECT_RISK = { - 100000000: 'Низкий', - 100000001: 'Средний', - 100000002: 'Высокий', -}; - -const computedEffects = { - // leadName() { - // const leadid = this.values.lead; - // if (this.options.selectLead && this.options.selectLead.length) { - // const lead = this.getOption('selectLead', { leadid }); - // if (lead) { - // return lead.name; - // } - // } - // }, - // opportunityName() { - // const opportunityid = this.values.opportunity; - // if ( - // this.options.selectOpportunity && - // this.options.selectOpportunity.length > 0 - // ) { - // const opportunity = this.getOption('selectOpportunity', { - // opportunityid, - // }); - // if (opportunity) { - // return opportunity.name; - // } - // } - // }, - leaseObjectRiskName() { - const configuration = this.getOption('selectConfiguration'); - if (configuration) { - if (configuration.evo_leasingobject_risk) { - const res = LEASE_OBJECT_RISK[configuration.evo_leasingobject_risk]; - return res; - } - } - - const model = this.getOption('selectModel'); - if (model) { - const evo_leasingobject_risk = model.evo_leasingobject_risk; - return LEASE_OBJECT_RISK[evo_leasingobject_risk]; - } - }, - insKaskoPriceLeasePeriod() { - return customValues.insKaskoPriceLeasePeriod.call(this).toFixed(2); - }, - irrInfo() { - const tarif = this.getOption('selectTarif'); - if (tarif && tarif.evo_min_irr && tarif.evo_max_irr) { - return `Min: ${tarif.evo_min_irr}% - Max: ${tarif.evo_max_irr}%`; - } - return '-'; - }, - registrationDescription() { - const registration = this.getOption('selectRegistration'); - if (registration && registration.evo_description) { - return registration.evo_description; - } - }, -}; - -export default computedEffects; diff --git a/src/client/stores/CalculationStore/Effects/computed.ts b/src/client/stores/CalculationStore/Effects/computed.ts new file mode 100644 index 0000000..1c1432a --- /dev/null +++ b/src/client/stores/CalculationStore/Effects/computed.ts @@ -0,0 +1,44 @@ +import { ICalculationStore } from 'core/types/Calculation/Store'; +import { TValues } from 'core/types/Calculation/Store/values'; +import customValues from './lib/customValues'; + +const LEASE_OBJECT_RISK = { + 100000000: 'Низкий', + 100000001: 'Средний', + 100000002: 'Высокий', +}; + +const computedEffects: TValues< + (this: ICalculationStore) => string | number | undefined +> = { + leaseObjectRiskName: function () { + const configuration = this.getOption('selectConfiguration'); + if (configuration) { + if (configuration.evo_leasingobject_risk) { + const res = LEASE_OBJECT_RISK[configuration.evo_leasingobject_risk]; + return res; + } + } + + const model = this.getOption('selectModel'); + const evo_leasingobject_risk = model?.evo_leasingobject_risk; + if (evo_leasingobject_risk) + return LEASE_OBJECT_RISK[evo_leasingobject_risk]; + }, + insKaskoPriceLeasePeriod: function () { + return customValues.insKaskoPriceLeasePeriod.call(this).toFixed(2); + }, + irrInfo: function () { + const tarif = this.getOption('selectTarif'); + if (tarif && tarif.evo_min_irr && tarif.evo_max_irr) { + return `Min: ${tarif.evo_min_irr}% - Max: ${tarif.evo_max_irr}%`; + } + return '-'; + }, + registrationDescription: function () { + const registration = this.getOption('selectRegistration'); + return registration?.evo_description; + }, +}; + +export default computedEffects; diff --git a/src/client/stores/CalculationStore/Effects/lib/queries.js b/src/client/stores/CalculationStore/Effects/lib/queries.js index 1ce4d99..2afc5b0 100644 --- a/src/client/stores/CalculationStore/Effects/lib/queries.js +++ b/src/client/stores/CalculationStore/Effects/lib/queries.js @@ -17,4 +17,8 @@ offerprintformapi evo_regionid evo_legal_regionid evo_legal_townid +link +evo_req_telematic +evo_req_telematic_accept +evo_one_year_insurance `; diff --git a/src/client/stores/CalculationStore/Effects/lib/tools.js b/src/client/stores/CalculationStore/Effects/lib/tools.js index 7e334b7..b30f3bf 100644 --- a/src/client/stores/CalculationStore/Effects/lib/tools.js +++ b/src/client/stores/CalculationStore/Effects/lib/tools.js @@ -1,12 +1,8 @@ -export function convertPrice( - isocurrencycode, - leaseObjectPrice, - evo_currencychange, -) { - let price = leaseObjectPrice; +export function convertPrice(isocurrencycode, targetPrice, evo_currencychange) { + let price = targetPrice; const isRUB = !isocurrencycode || isocurrencycode === 'RUB'; if (!isRUB) { - price = leaseObjectPrice * evo_currencychange; + price = targetPrice * evo_currencychange; } return price; } diff --git a/src/client/stores/CalculationStore/Effects/reactions/eltReactions.ts b/src/client/stores/CalculationStore/Effects/reactions/eltReactions.ts index 88428d6..0c987e8 100644 --- a/src/client/stores/CalculationStore/Effects/reactions/eltReactions.ts +++ b/src/client/stores/CalculationStore/Effects/reactions/eltReactions.ts @@ -1,7 +1,10 @@ import { message } from 'antd'; import { resetFields as kaskoResetFields } from 'client/Components/Calculation/ELT/Content/Kasko/lib/validation'; import { cancelRequests } from 'client/Components/Calculation/ELT/Content/lib/requests'; -import { resetIns } from 'client/Components/Calculation/ELT/Content/lib/resetIns'; +import { + initIns, + resetIns, +} from 'client/Components/Calculation/ELT/Content/lib/resetIns'; import { resetFields as osagoResetFields } from 'client/Components/Calculation/ELT/Content/Osago/lib/validation'; import { getValueName } from 'client/Containers/Calculation/lib/elements/tools'; import { TCalculationProcess } from 'client/stores/CalculationStore/subStores/calculationProcess'; @@ -29,6 +32,18 @@ const RESET_MESSAGES = { }; const eltReactions: IReactionEffect[] = [ + calculationStore => ({ + expression: () => { + return calculationStore.getOption('selectLeaseObjectType'); + }, + effect: (prevLeaseObjectType, nextLeaseObjectType) => { + if ( + prevLeaseObjectType?.evo_id === '9' || + nextLeaseObjectType?.evo_id === '9' + ) + initIns.call(calculationStore, 'kasko'); + }, + }), ...resetConf.map( ({ insType, resetFields }) => ( calculationStore: ICalculationStore, @@ -36,20 +51,22 @@ const eltReactions: IReactionEffect[] = [ ) => ({ expression: () => { return calculationStore.getValues( - //@ts-ignore (resetFields as ElementsNames[]).map(getValueName), ); }, effect: () => { cancelRequests(insType); + if ( + calculationProcess.hasProcess(Process.Init) || calculationProcess.hasProcess(Process.ELT) || calculationProcess.hasProcess(Process.LoadKp) ) { return; } + const { ELTStore } = calculationStore.stores; - if (ELTStore[insType].isReseted() === true) { + if (ELTStore[insType]?.isReseted()) { return; } message.warn({ content: RESET_MESSAGES[insType] }); @@ -75,14 +92,17 @@ const eltReactions: IReactionEffect[] = [ }, effect: () => { cancelRequests(insType); + if ( + calculationProcess.hasProcess(Process.Init) || calculationProcess.hasProcess(Process.ELT) || calculationProcess.hasProcess(Process.LoadKp) ) { return; } + const { ELTStore } = calculationStore.stores; - if (ELTStore[insType].isReseted() === true) { + if (ELTStore[insType]?.isReseted()) { return; } message.warn({ content: RESET_MESSAGES[insType] }); diff --git a/src/client/stores/CalculationStore/Effects/reactions/gibddReactions.ts b/src/client/stores/CalculationStore/Effects/reactions/gibddReactions.ts index 6d245ae..a2438f6 100644 --- a/src/client/stores/CalculationStore/Effects/reactions/gibddReactions.ts +++ b/src/client/stores/CalculationStore/Effects/reactions/gibddReactions.ts @@ -169,8 +169,11 @@ const gibddReactions: IReactionEffect[] = [ expression: () => { return calculationStore.getOption('selectLeaseObjectType'); }, - effect: ({ evo_category }) => { - calculationStore.setValue('leaseObjectCategory', evo_category); + effect: selectLeaseObjectType => { + calculationStore.setValue( + 'leaseObjectCategory', + selectLeaseObjectType?.evo_category, + ); }, options: { fireImmediately: true, @@ -347,6 +350,7 @@ const gibddReactions: IReactionEffect[] = [ 'objectRegistration', 'regionRegistration', 'typePTS', + 'leaseObjectCategory', ]), }; }, @@ -355,17 +359,26 @@ const gibddReactions: IReactionEffect[] = [ objectRegionRegistration, regionRegistration, typePTS, + leaseObjectCategory, }) => { calculationStore.setFilter('selectRegistration', options => options.filter(x => { - if (!(x.evo_whom_register === objectRegistration)) { + if (!objectRegionRegistration && !regionRegistration) { + return false; + } + + if (!(x?.evo_whom_register === objectRegistration)) { + return false; + } + + if (leaseObjectCategory !== 100000001 && x?.evo_towtruck) { return false; } if ( !( - x.evo_gibdd_region === - (objectRegionRegistration.evo_regionid === regionRegistration) + x?.evo_gibdd_region === + (objectRegionRegistration?.evo_regionid === regionRegistration) ) ) { return false; @@ -373,23 +386,26 @@ const gibddReactions: IReactionEffect[] = [ if ( (typePTS && - (!x.evo_pts_type || - x.evo_pts_type.filter(t => t > 0).length === 0)) || - x.evo_pts_type?.filter(t => t > 0).includes(typePTS) === false + (!x?.evo_pts_type || + x?.evo_pts_type.filter(t => t > 0).length === 0)) || + x?.evo_pts_type?.filter(t => t > 0).includes(typePTS) === false ) { return false; } - if (!x.evo_accountid) { + if (!x?.evo_accountid) { return true; } - return objectRegionRegistration.accounts - .map(r => r.accountid) + return objectRegionRegistration?.accounts + ?.map(r => r.accountid) .includes(x.evo_accountid); }), ); }, + options: { + fireImmediately: true, + }, }), (calculationStore, calculationProcess) => ({ @@ -588,7 +604,10 @@ const gibddReactions: IReactionEffect[] = [ calculationStore => ({ expression: () => { - return calculationStore.getValue('regionRegistration'); + return calculationStore.getValues([ + 'regionRegistration', + 'objectRegistration', + ]); }, effect: () => { const objectRegistration = calculationStore.getValue( diff --git a/src/client/stores/CalculationStore/Effects/reactions/index.ts b/src/client/stores/CalculationStore/Effects/reactions/index.ts index 998d83c..3247701 100644 --- a/src/client/stores/CalculationStore/Effects/reactions/index.ts +++ b/src/client/stores/CalculationStore/Effects/reactions/index.ts @@ -1,6 +1,7 @@ import eltReactions from './eltReactions'; import gibddReactions from './gibddReactions'; import insuranceReactions from './insuranceReactions'; +import linkReactions from './linkReactions'; import loadKpReaction from './loadKpReaction'; import otherReactions from './otherReactions'; import priceReactions from './priceReactions'; @@ -19,5 +20,6 @@ export default [ ...gibddReactions, ...eltReactions, ...insuranceReactions, + ...linkReactions, loadKpReaction, ]; diff --git a/src/client/stores/CalculationStore/Effects/reactions/insuranceReactions.ts b/src/client/stores/CalculationStore/Effects/reactions/insuranceReactions.ts index aa77463..3f8de66 100644 --- a/src/client/stores/CalculationStore/Effects/reactions/insuranceReactions.ts +++ b/src/client/stores/CalculationStore/Effects/reactions/insuranceReactions.ts @@ -32,6 +32,8 @@ const mapObjectCategoryToUseFor = { 100000013, ], 100000004: [100000002, 100000009], + null: [100000014, 100000015, 100000016, 100000017, 100000018, 100000019], + undefined: [100000014, 100000015, 100000016, 100000017, 100000018, 100000019], }; const insuranceReactions: IReactionEffect[] = [ @@ -40,21 +42,16 @@ const insuranceReactions: IReactionEffect[] = [ return calculationStore.getValue('leaseObjectCategory'); }, effect: leaseObjectCategory => { - if (leaseObjectCategory) { - const allowedObjectUseFor: number[] = - mapObjectCategoryToUseFor[leaseObjectCategory]; - calculationStore.setFilter('selectLeaseObjectUseFor', options => - options.filter( - option => - option.value && - typeof option.value === 'number' && - allowedObjectUseFor && - allowedObjectUseFor.includes(option.value), - ), - ); - } else { - calculationStore.setFilter('selectLeaseObjectUseFor', undefined); - } + const allowedObjectUseFor: number[] = + mapObjectCategoryToUseFor[leaseObjectCategory]; + calculationStore.setFilter('selectLeaseObjectUseFor', options => + options.filter( + option => + option.value && + typeof option.value === 'number' && + allowedObjectUseFor?.includes(option.value), + ), + ); }, }), diff --git a/src/client/stores/CalculationStore/Effects/reactions/linkReactions.ts b/src/client/stores/CalculationStore/Effects/reactions/linkReactions.ts new file mode 100644 index 0000000..96a73dd --- /dev/null +++ b/src/client/stores/CalculationStore/Effects/reactions/linkReactions.ts @@ -0,0 +1,21 @@ +import { IReactionEffect } from 'core/types/Calculation/Store/effect'; +import { ElementsNames } from 'core/types/Calculation/Store/elements'; +import { LinksNames } from 'core/types/Calculation/Store/links'; + +export default ([ + { elementName: 'selectLead', urlName: 'leadUrl' }, + { elementName: 'selectOpportunity', urlName: 'opportunityUrl' }, + { elementName: 'selectQuote', urlName: 'quoteUrl' }, +] as { + elementName: ElementsNames; + urlName: LinksNames; +}[]).map(({ elementName, urlName }) => calculationStore => ({ + expression: () => { + return calculationStore.getOption(elementName); + }, + effect: targetEntity => { + const { calculationUrls } = calculationStore.stores; + const link = targetEntity?.link ?? undefined; + calculationUrls.setUrl({ name: urlName, url: link }); + }, +})) as IReactionEffect[]; diff --git a/src/client/stores/CalculationStore/Effects/reactions/loadKpReaction/index.ts b/src/client/stores/CalculationStore/Effects/reactions/loadKpReaction/index.ts index 36be9b3..87bffac 100644 --- a/src/client/stores/CalculationStore/Effects/reactions/loadKpReaction/index.ts +++ b/src/client/stores/CalculationStore/Effects/reactions/loadKpReaction/index.ts @@ -13,7 +13,7 @@ import { Process } from 'core/types/Calculation/Store/process'; import { ValuesNames } from 'core/types/Calculation/Store/values'; import { IEvoGraph } from 'core/types/Entities/crmEntities'; import { ElementStatus } from 'core/types/statuses'; -import { get, isNil } from 'lodash'; +import { get, invert, isEqual, isNil } from 'lodash'; import NIL from 'uuid/dist/nil'; import { getKpPropName } from './mapKpToValues'; import { mainOptionsQuery, secondaryOptionsQuery } from './optionsQuery'; @@ -24,7 +24,8 @@ const map_add_product_types_to_values = { registration: 100000001, insNSIB: 100000002, tracker: 100000003, - telematics: 100000004, + telematic: 100000004, + fuelCard: 100000005, }; const tablePaymentsStatuses = (graphType, leasingPeriod) => { @@ -57,13 +58,14 @@ const loadKpReaction: IReactionEffect = calculationStore => ({ lead, opportunity, recalcWithRevision, - leaseObjectCount, calcType, indAgent, INNForCalc, creditRate, rate, infuranceOPF, + calcBroker, + calcFinDepartment, } = calculationStore.values; calculationStore.setStatus('selectQuote', ElementStatus.Disabled); @@ -109,11 +111,11 @@ const loadKpReaction: IReactionEffect = calculationStore => ({ dealer_person_accountid: quote.evo_dealer_person_accountid || NIL, dealer_broker_accountid: quote.evo_dealer_broker_accountid || NIL, hasDealerBroker: quote.evo_dealer_broker_accountid ? true : false, - ind_agent_accountid: quote.evo_agent_accountid || NIL, + // ind_agent_accountid: quote.evo_agent_accountid || NIL, double_agent_accountid: quote.evo_double_agent_accountid || NIL, - broker_accountid: quote.evo_broker_accountid || NIL, - findepartment_accountid: - quote.evo_fin_department_accountid || NIL, + // broker_accountid: quote.evo_broker_accountid || NIL, + // findepartment_accountid: + // quote.evo_fin_department_accountid || NIL, evo_gps_brandid: quote.evo_gps_brandid || NIL, evo_regionid: quote.evo_regionid || NIL, evo_legal_regionid: quote.evo_legal_regionid || NIL, @@ -228,19 +230,17 @@ const loadKpReaction: IReactionEffect = calculationStore => ({ // get product evo_id // get addproducts - const addProducts = Object.assign( + let addProducts = Object.assign( {}, - ...Object.keys(map_add_product_types_to_values).map(elementName => { + ...Object.keys(map_add_product_types_to_values).map(valueName => { const target_add_product_type = quote?.evo_addproduct_types?.find( x => x.evo_product_type === - map_add_product_types_to_values[elementName], + map_add_product_types_to_values[valueName], ); return { - [elementName]: - target_add_product_type && - target_add_product_type.evo_addproduct_typeid, + [valueName]: target_add_product_type?.evo_addproduct_typeid, }; }), ); @@ -283,13 +283,35 @@ const loadKpReaction: IReactionEffect = calculationStore => ({ // get clientRisk // recalc fields - let requirementTelematic = quote['evo_req_telematic']; let vehicleTaxInYear = quote['evo_vehicle_tax_year']; + let leaseObjectCount = quote.evo_object_count; + let requirementTelematic = quote.evo_req_telematic; if (recalcWithRevision) { + requirementTelematic = quote.evo_req_telematic_accept; if (quote['evo_vehicle_tax_approved']) { vehicleTaxInYear = quote['evo_vehicle_tax_approved']; } - requirementTelematic = quote['evo_req_telematic_accept']; + if (quote.evo_recalc_limit) { + leaseObjectCount = quote.evo_recalc_limit; + } + // telematic/tracker + addProducts.telematic = undefined; + addProducts.tracker = undefined; + const add_product_types = calculationStore.getStaticData( + 'evo_addproduct_type', + ); + const targetAddproduct = add_product_types.find( + x => + x.evo_addproduct_typeid === + quote.evo_accept_control_addproduct_typeid, + ); + if (targetAddproduct?.evo_product_type) { + const targetAddProductValueName = invert( + map_add_product_types_to_values, + )[targetAddproduct?.evo_product_type]; + addProducts[targetAddProductValueName] = + targetAddproduct.evo_addproduct_typeid; + } } // recalc fields @@ -460,31 +482,36 @@ const loadKpReaction: IReactionEffect = calculationStore => ({ //townRegistration } - calculationStore.setValues({ - ...initialValues, - ...newValues, - product, - ...addProducts, - rate, - lead, - opportunity, - quote: quoteId, - recalcWithRevision, - leaseObjectCount, - clientRisk, - calcType, - totalPayments: evo_graph.evo_sumpay_withnds, - indAgent, - requirementTelematic, - vehicleTaxInYear, - INNForCalc, - creditRate, - infuranceOPF, - legalClientRegion, - regionRegistration, - legalClientTown, - townRegistration, - }); + calculationStore.setValues( + { + ...initialValues, + ...newValues, + product, + ...addProducts, + rate, + lead, + opportunity, + quote: quoteId, + recalcWithRevision, + leaseObjectCount, + clientRisk, + calcType, + totalPayments: evo_graph.evo_sumpay_withnds, + indAgent, + vehicleTaxInYear, + INNForCalc, + creditRate, + infuranceOPF, + legalClientRegion, + regionRegistration, + legalClientTown, + townRegistration, + calcBroker, + calcFinDepartment, + requirementTelematic, + }, + true, + ); message.success({ content: `КП ${quote?.evo_quotename || ''} загружено!`, @@ -498,7 +525,7 @@ const loadKpReaction: IReactionEffect = calculationStore => ({ x => x.accountid === quote.evo_kasko_accountid, ); - if (kaskoIndex !== undefined) { + if (kaskoIndex >= 0) { const mapQuoteToELTKasko = { key: 'evo_kasko_accountid', accountid: 'evo_kasko_accountid', @@ -530,7 +557,7 @@ const loadKpReaction: IReactionEffect = calculationStore => ({ const osagoIndex = ELTStore.osago.list.findIndex( x => x.accountid === quote.evo_osago_accountid, ); - if (osagoIndex !== undefined) { + if (osagoIndex >= 0) { const mapQuoteToELTOsago = { key: 'evo_osago_accountid', accountid: 'evo_osago_accountid', @@ -545,15 +572,11 @@ const loadKpReaction: IReactionEffect = calculationStore => ({ if (!isNil(quoteValue)) row[rowFieldName] = quoteValue; }); - //fix with Serega - row['evo_id_elt_osago'] = quote.evo_id_elt_osago - ? parseInt(quote.evo_id_elt_osago) - : undefined; + if (row['numCalc']) { + row['numCalc'] = parseInt(row['numCalc']); + } - if ( - Object.keys(mapQuoteToELTOsago).length === - Object.keys(row).length - ) { + if (isEqual(Object.keys(row), Object.keys(mapQuoteToELTOsago))) { ELTStore.addToCompanyRes('osago', osagoIndex, row); ELTStore.osago.setKey(quote.evo_osago_accountid); } diff --git a/src/client/stores/CalculationStore/Effects/reactions/loadKpReaction/mapKpToValues.ts b/src/client/stores/CalculationStore/Effects/reactions/loadKpReaction/mapKpToValues.ts index 5dec30a..6149ece 100644 --- a/src/client/stores/CalculationStore/Effects/reactions/loadKpReaction/mapKpToValues.ts +++ b/src/client/stores/CalculationStore/Effects/reactions/loadKpReaction/mapKpToValues.ts @@ -1,7 +1,7 @@ import { TValues, ValuesNames } from 'core/types/Calculation/Store/values'; -// import { TCRMEntity } from 'core/types/Entities/crmEntities'; +import { IQuote } from 'core/types/Entities/crmEntities'; -const mapKPtoValues: TValues = { +const mapKPtoValues: TValues = { product: 'evo_baseproductid', clientType: 'evo_client_typeid', leaseObjectPrice: 'evo_supplier_currency_price', @@ -53,10 +53,10 @@ const mapKPtoValues: TValues = { calcDoubleAgent: 'evo_double_agent_accountid', calcDoubleAgentRewardCondition: 'evo_double_agent_reward_conditionid', calcDoubleAgentRewardSumm: 'evo_double_agent_reward_total', - calcBroker: 'evo_broker_accountid', + // calcBroker: 'evo_broker_accountid', calcBrokerRewardCondition: 'evo_broker_reward_conditionid', calcBrokerRewardSum: 'evo_broker_reward_total', - calcFinDepartment: 'evo_fin_department_accountid', + // calcFinDepartment: 'evo_fin_department_accountid', finDepartmentRewardCondtion: 'evo_fin_department_reward_conditionid', finDepartmentRewardSumm: 'evo_fin_department_reward_total', GPSBrand: 'evo_gps_brandid', @@ -92,6 +92,8 @@ const mapKPtoValues: TValues = { objectCategoryTax: 'evo_category_tr', objectTypeTax: 'evo_vehicle_type_tax', typePTS: 'evo_pts_type', + subsidy: 'evo_subsidyid', + subsidySum: 'evo_subsidy_summ', }; export function getKpPropName(valueName: ValuesNames) { diff --git a/src/client/stores/CalculationStore/Effects/reactions/loadKpReaction/optionsQuery.js b/src/client/stores/CalculationStore/Effects/reactions/loadKpReaction/optionsQuery.js index 3efa0a3..82f40bc 100644 --- a/src/client/stores/CalculationStore/Effects/reactions/loadKpReaction/optionsQuery.js +++ b/src/client/stores/CalculationStore/Effects/reactions/loadKpReaction/optionsQuery.js @@ -10,10 +10,10 @@ export const mainOptionsQuery = gql` $dealer_person_accountid: Uuid! $dealer_broker_accountid: Uuid! $hasDealerBroker: Boolean! - $ind_agent_accountid: Uuid! + # $ind_agent_accountid: Uuid! $double_agent_accountid: Uuid! - $broker_accountid: Uuid! - $findepartment_accountid: Uuid! + # $broker_accountid: Uuid! + # $findepartment_accountid: Uuid! $evo_gps_brandid: Uuid! ) { selectModel: evo_models(statecode: $statecode, evo_brandid: $evo_brandid) { @@ -26,6 +26,10 @@ export const mainOptionsQuery = gql` evo_impairment_groupid evo_vehicle_type evo_gps + evo_vehicle_body_typeidData { + evo_id_elt + } + evo_running_gear } selectConfiguration: evo_equipments( statecode: $statecode @@ -45,6 +49,7 @@ export const mainOptionsQuery = gql` name evo_broker_accountid evo_kpp + evo_inn } selectDealerRewardCondition: evo_reward_conditions( evo_agent_accountid: $dealer_person_accountid @@ -73,18 +78,18 @@ export const mainOptionsQuery = gql` evo_reward_summ evo_reduce_reward } - selectIndAgentRewardCondition: evo_reward_conditions( - evo_agent_accountid: $ind_agent_accountid - evo_datefrom_param: { lte: $currentDate } - evo_dateto_param: { gte: $currentDate } - statecode: $statecode - ) { - evo_reward_conditionid - evo_name - evo_double_agent_accountid - evo_reward_summ - evo_reduce_reward - } + # selectIndAgentRewardCondition: evo_reward_conditions( + # evo_agent_accountid: $ind_agent_accountid + # evo_datefrom_param: { lte: $currentDate } + # evo_dateto_param: { gte: $currentDate } + # statecode: $statecode + # ) { + # evo_reward_conditionid + # evo_name + # evo_double_agent_accountid + # evo_reward_summ + # evo_reduce_reward + # } calcDoubleAgentRewardCondition: evo_reward_conditions( evo_agent_accountid: $double_agent_accountid evo_datefrom_param: { lte: $currentDate } @@ -96,28 +101,28 @@ export const mainOptionsQuery = gql` evo_reward_summ evo_reduce_reward } - calcBrokerRewardCondition: evo_reward_conditions( - evo_agent_accountid: $broker_accountid - evo_datefrom_param: { lte: $currentDate } - evo_dateto_param: { gte: $currentDate } - statecode: $statecode - ) { - evo_reward_conditionid - evo_name - evo_reward_summ - evo_reduce_reward - } - selectFinDepartmentRewardCondtion: evo_reward_conditions( - evo_agent_accountid: $findepartment_accountid - evo_datefrom_param: { lte: $currentDate } - evo_dateto_param: { gte: $currentDate } - statecode: $statecode - ) { - evo_reward_conditionid - evo_name - evo_reward_summ - evo_reduce_reward - } + # calcBrokerRewardCondition: evo_reward_conditions( + # evo_agent_accountid: $broker_accountid + # evo_datefrom_param: { lte: $currentDate } + # evo_dateto_param: { gte: $currentDate } + # statecode: $statecode + # ) { + # evo_reward_conditionid + # evo_name + # evo_reward_summ + # evo_reduce_reward + # } + # selectFinDepartmentRewardCondtion: evo_reward_conditions( + # evo_agent_accountid: $findepartment_accountid + # evo_datefrom_param: { lte: $currentDate } + # evo_dateto_param: { gte: $currentDate } + # statecode: $statecode + # ) { + # evo_reward_conditionid + # evo_name + # evo_reward_summ + # evo_reduce_reward + # } selectGPSModel: evo_gps_models( statecode: $statecode evo_gps_brandid: $evo_gps_brandid diff --git a/src/client/stores/CalculationStore/Effects/reactions/loadKpReaction/quoteQuery.js b/src/client/stores/CalculationStore/Effects/reactions/loadKpReaction/quoteQuery.js index 678a437..9f74281 100644 --- a/src/client/stores/CalculationStore/Effects/reactions/loadKpReaction/quoteQuery.js +++ b/src/client/stores/CalculationStore/Effects/reactions/loadKpReaction/quoteQuery.js @@ -8,7 +8,7 @@ export default gql` evo_addproduct_types { evo_product_type evo_addproduct_typeid - } + } evo_osago_accountid evo_kasko_accountid evo_osago_payer @@ -37,8 +37,6 @@ export default gql` evo_vehicle_tax_year evo_category_tr evo_vehicle_type_tax - evo_req_telematic_accept - evo_req_telematic evo_agent_accountid evo_dealer_person_accountid evo_dealer_broker_accountid @@ -55,6 +53,11 @@ export default gql` evo_osago_price evo_legal_regionid evo_legal_townid + evo_object_count + evo_recalc_limit + evo_req_telematic + evo_req_telematic_accept + evo_accept_control_addproduct_typeid } } `; diff --git a/src/client/stores/CalculationStore/Effects/reactions/otherReactions.ts b/src/client/stores/CalculationStore/Effects/reactions/otherReactions.ts index 734655b..c011395 100644 --- a/src/client/stores/CalculationStore/Effects/reactions/otherReactions.ts +++ b/src/client/stores/CalculationStore/Effects/reactions/otherReactions.ts @@ -1231,10 +1231,19 @@ const reactionEffects: IReactionEffect[] = [ }, effect: leaseObjectUsed => { if (leaseObjectUsed === true) { - calculationStore.setValue('deliveryTime', 100000000); - calculationStore.setStatus('radioDeliveryTime', ElementStatus.Disabled); + calculationStore.setValues({ + deliveryTime: 100000000, + subsidy: null, + }); + calculationStore.setStatuses({ + radioDeliveryTime: ElementStatus.Disabled, + selectSubsidy: ElementStatus.Disabled, + }); } else { - calculationStore.setStatus('radioDeliveryTime', ElementStatus.Default); + calculationStore.setStatuses({ + radioDeliveryTime: ElementStatus.Default, + selectSubsidy: ElementStatus.Default, + }); } }, options: { @@ -1365,11 +1374,11 @@ const reactionEffects: IReactionEffect[] = [ calculationStore => ({ expression: () => { - const { product, leasingPeriod } = calculationStore.values; - return { product_evo_id: product, leasingPeriod }; + const { product, leasingPeriod, deliveryTime } = calculationStore.values; + return { product_evo_id: product, leasingPeriod, deliveryTime }; }, - effect: ({ product_evo_id, leasingPeriod }) => { - if (product_evo_id && leasingPeriod) { + effect: ({ product_evo_id, leasingPeriod, deliveryTime }) => { + if (product_evo_id && leasingPeriod && deliveryTime) { const product = calculationStore.getOption('selectProduct', { evo_id: product_evo_id, }); @@ -1380,7 +1389,8 @@ const reactionEffects: IReactionEffect[] = [ x.evo_min_period && x.evo_min_period <= leasingPeriod && x.evo_max_period && - x.evo_max_period >= leasingPeriod, + x.evo_max_period >= leasingPeriod && + x.evo_delivery_time?.includes(deliveryTime), ); calculationStore.setValue('tarif', tarif?.evo_tarifid); } @@ -1419,9 +1429,32 @@ const reactionEffects: IReactionEffect[] = [ calculationStore.setFilter('selectTechnicalCard', options => options.filter( x => - x && - x.evo_max_period && - x.evo_min_period && + x?.evo_max_period && + x?.evo_min_period && + x.evo_max_period >= leasingPeriod && + x.evo_min_period <= leasingPeriod && + x.evo_leasingobject_types?.find( + x => x.evo_leasingobject_typeid === leaseObjectType, + ), + ), + ); + }, + options: { + fireImmediately: true, + }, + }), + + calculationStore => ({ + expression: () => { + const { leasingPeriod, leaseObjectType } = calculationStore.values; + return { leasingPeriod, leaseObjectType }; + }, + effect: ({ leasingPeriod, leaseObjectType }) => { + calculationStore.setFilter('selectFuelCard', options => + options.filter( + x => + x?.evo_max_period && + x?.evo_min_period && x.evo_max_period >= leasingPeriod && x.evo_min_period <= leasingPeriod && x.evo_leasingobject_types?.find( @@ -1487,6 +1520,37 @@ const reactionEffects: IReactionEffect[] = [ }, }), + (calculationStore, calculationProcess) => ({ + expression: () => { + return calculationStore.getValue('leasingPeriod'); + }, + effect: () => { + if (calculationProcess.hasProcess(Process.LoadKp)) { + return; + } + + const fuelCard = calculationStore.getOption('selectFuelCard'); + if (fuelCard) { + const selectFuelCard_filter = calculationStore.getFilter( + 'selectFuelCard', + ); + const selectFueldCard_options = calculationStore.getOptions( + 'selectFuelCard', + ); + + if (selectFuelCard_filter && selectFueldCard_options) { + const filtered_technicalCards = selectFuelCard_filter( + selectFueldCard_options, + ); + calculationStore.setValue( + 'fuelCard', + filtered_technicalCards?.[0]?.evo_addproduct_typeid, + ); + } + } + }, + }), + calculationStore => ({ expression: () => { const { @@ -1635,7 +1699,7 @@ const reactionEffects: IReactionEffect[] = [ ); break; } - case 100000002: { + case 100000001: { calculationStore.setStatus('tbxIRR_Perc', ElementStatus.Disabled); calculationStore.setStatus('tbxTotalPayments', ElementStatus.Default); break; @@ -1679,38 +1743,39 @@ const reactionEffects: IReactionEffect[] = [ return { leaseObjectType: calculationStore.getOption('selectLeaseObjectType'), product: calculationStore.getOption('selectProduct'), + subsidy: calculationStore.getOption('selectSubsidy'), }; }, - effect: ({ leaseObjectType, product }) => { + effect: ({ leaseObjectType, product, subsidy }) => { calculationStore.setStatus( 'selectBrand', leaseObjectType ? ElementStatus.Default : ElementStatus.Disabled, ); - calculationStore.setFilter('selectBrand', options => - options.filter( + calculationStore.setFilter('selectBrand', brands => + brands.filter( pipe( - option => { - if ( - product && - product.evo_brands && - product.evo_brands.length > 0 - ) { - return ( - product.evo_brands - .map(x => x.evo_brandid) - .includes(option.evo_brandid) && option - ); - } - return option; - }, + brand => + (!product?.evo_brands?.length || + product.evo_brands.filter( + x => x.evo_brandid === brand?.evo_brandid, + )?.length) && + brand, - option => - option.evo_vehicle_type && + brand => + brand?.evo_vehicle_type && intersection( - option.evo_vehicle_type?.filter(x => x > 0), + brand.evo_vehicle_type?.filter(x => x > 0), leaseObjectType.evo_vehicle_type, - ).length > 0, + ).length > 0 && + brand, + + brand => + brand && + (!subsidy?.evo_brands || + subsidy?.evo_brands?.filter( + x => x.evo_brandid === brand.evo_brandid, + )?.length), ), ), ); @@ -1725,19 +1790,64 @@ const reactionEffects: IReactionEffect[] = [ return { selectBrandOptions: calculationStore.getOption('selectBrand'), selectBrandFilter: calculationStore.getFilter('selectBrand'), + subsidy: calculationStore.getOption('selectSubsidy'), }; }, - effect: () => { + effect: ({ subsidy }) => { const leaseObjectType = calculationStore.getOption( 'selectLeaseObjectType', ); calculationStore.setFilter('selectModel', options => options.filter( - model => - model.evo_vehicle_type && - leaseObjectType && - leaseObjectType.evo_vehicle_type && - leaseObjectType.evo_vehicle_type.includes(model.evo_vehicle_type), + pipe( + model => + model.evo_vehicle_type && + leaseObjectType?.evo_vehicle_type?.includes( + model.evo_vehicle_type, + ) && + model, + model => + model && + (!subsidy?.evo_models?.length || + subsidy?.evo_models?.filter( + x => x.evo_modelid === model.evo_modelid, + )?.length), + ), + ), + ); + }, + }), + + calculationStore => ({ + expression: () => { + return calculationStore.getOption('selectSubsidy'); + }, + effect: subsidy => { + calculationStore.setFilter('selectLeaseObjectType', types => + types.filter( + type => + !subsidy?.evo_leasingobject_types || + subsidy.evo_leasingobject_types.filter( + x => x.evo_leasingobject_typeid === type.evo_leasingobject_typeid, + )?.length, + ), + ); + + calculationStore.setFilter('selectDealer', dealers => + dealers.filter( + dealer => + !subsidy?.accounts || + subsidy.accounts.filter(x => x.accountid === dealer.accountid) + ?.length, + ), + ); + + calculationStore.setFilter('selectDealerPerson', dealerPersons => + dealerPersons.filter( + dealerPerson => + !subsidy?.accounts || + subsidy.accounts.filter(x => x.accountid === dealerPerson.accountid) + ?.length, ), ); }, @@ -1767,6 +1877,57 @@ const reactionEffects: IReactionEffect[] = [ ); }, }), + + calculationStore => ({ + expression: () => { + return calculationStore.getOption('selectTarif'); + }, + effect: tarif => { + const ratesOptions = calculationStore.getOptions('selectRate'); + if (!ratesOptions) { + return; + } + + let rates = ratesOptions.filter( + rate => + rate?.evo_tarifs?.filter( + evo_tarif => evo_tarif?.evo_tarifid === tarif?.evo_tarifid, + ).length, + ); + + if (!rates?.length) { + rates = ratesOptions.filter(rate => rate.evo_id === 'BASE'); + } + + calculationStore.setValue('rate', rates[0].evo_id); + }, + }), + + calculationStore => ({ + expression: () => { + return calculationStore.getOption('selectSubsidy'); + }, + effect: subsidy => { + if (subsidy) { + calculationStore.setValues({ + leaseObjectCount: 1, + leaseObjectUsed: false, + deliveryTime: 100000000, + }); + } + calculationStore.setStatuses({ + tbxLeaseObjectCount: subsidy + ? ElementStatus.Disabled + : ElementStatus.Default, + cbxLeaseObjectUsed: subsidy + ? ElementStatus.Disabled + : ElementStatus.Default, + radioDeliveryTime: subsidy + ? ElementStatus.Disabled + : ElementStatus.Default, + }); + }, + }), ]; export default reactionEffects; diff --git a/src/client/stores/CalculationStore/Effects/reactions/recalcWoRevisionReactions.ts b/src/client/stores/CalculationStore/Effects/reactions/recalcWoRevisionReactions.ts index acebff8..0e60198 100644 --- a/src/client/stores/CalculationStore/Effects/reactions/recalcWoRevisionReactions.ts +++ b/src/client/stores/CalculationStore/Effects/reactions/recalcWoRevisionReactions.ts @@ -2,6 +2,7 @@ import { openNotification } from 'client/Elements/Notification'; import valuesConstants from 'core/constants/values'; import { IReactionEffect } from 'core/types/Calculation/Store/effect'; import { ElementsNames } from 'core/types/Calculation/Store/elements'; +import { Process } from 'core/types/Calculation/Store/process'; import { TableNames } from 'core/types/Calculation/Store/tables'; import { ElementStatus } from 'core/types/statuses'; import { convertPrice } from '../lib/tools'; @@ -193,17 +194,17 @@ const reactionEffects: IReactionEffect[] = [ calculationStore => ({ expression: () => { - const { quote, recalcWithRevision } = calculationStore.values; - return [quote, recalcWithRevision]; + const { recalcWithRevision } = calculationStore.values; + return recalcWithRevision; }, - effect: ([quoteid, recalcWithRevision]) => { - const quote = calculationStore.getOption('selectQuote', { quoteid }); + effect: recalcWithRevision => { + const quote = calculationStore.getOption('selectQuote'); if (recalcWithRevision) { - if (quote && quote.evo_recalc_limit) { + if (quote?.evo_recalc_limit) { calculationStore.setValue('leaseObjectCount', quote.evo_recalc_limit); } } else { - if (quote && quote.evo_object_count) { + if (quote?.evo_object_count) { calculationStore.setValue('leaseObjectCount', quote.evo_object_count); } } @@ -332,34 +333,127 @@ const reactionEffects: IReactionEffect[] = [ }, }), - calculationStore => ({ + (calculationStore, calculationProcess) => ({ expression: () => { - const recalcWithRevision = calculationStore.getValue( - 'recalcWithRevision', - ); - const leaseObjectType = calculationStore.getOption( - 'selectLeaseObjectType', - ); - return [recalcWithRevision, leaseObjectType]; + return { + recalcWithRevision: calculationStore.getValue('recalcWithRevision'), + leaseObjectType: calculationStore.getOption('selectLeaseObjectType'), + }; }, - effect: ([recalcWithRevision, leaseObjectType]) => { - calculationStore.setStatus( - 'radioRequirementTelematic', - ElementStatus.Default, - ); + effect: ({ recalcWithRevision, leaseObjectType }) => { + if (calculationProcess.hasProcess(Process.LoadKp)) { + return; + } if (!recalcWithRevision) { + const allowedReqTelematicValues = [100000000, 100000001]; calculationStore.setFilter('radioRequirementTelematic', options => - options.filter(x => x.value !== 100000003), + options.filter( + x => + x.value && + typeof x.value === 'number' && + allowedReqTelematicValues.includes(x?.value), + ), ); - if (leaseObjectType.evo_id === '11') { + if (leaseObjectType?.evo_id === '11') { calculationStore.setValue('requirementTelematic', 100000000); calculationStore.setStatus( 'radioRequirementTelematic', ElementStatus.Disabled, ); + } else { + calculationStore.setStatus( + 'radioRequirementTelematic', + ElementStatus.Default, + ); } } else { calculationStore.setFilter('radioRequirementTelematic', undefined); + calculationStore.setStatus( + 'radioRequirementTelematic', + ElementStatus.Disabled, + ); + } + }, + options: { + fireImmediately: true, + }, + }), + + calculationStore => ({ + expression: () => { + return calculationStore.getValue('recalcWithRevision'); + }, + effect: recalcWithRevision => { + if (!recalcWithRevision) { + const quote = calculationStore.getOption('selectQuote'); + if (quote) { + calculationStore.setValue( + 'requirementTelematic', + quote.evo_req_telematic, + ); + let addProducts = Object.assign( + {}, + ...Object.keys(map_add_product_types_to_values).map(valueName => { + const target_add_product_type = quote?.evo_addproduct_types?.find( + x => + x.evo_product_type === + map_add_product_types_to_values[valueName], + ); + + return { + [valueName]: target_add_product_type?.evo_addproduct_typeid, + }; + }), + ); + calculationStore.setValues(addProducts); + } else { + calculationStore.setValue('requirementTelematic', 100000000); + calculationStore.setValue('telematic', null); + + const addProducts = calculationStore.getStaticData( + 'evo_addproduct_type', + ); + const tracker = addProducts.find(x => + x.evo_controls_program?.includes(100000000), + ); + calculationStore.setValue('tracker', tracker?.evo_addproduct_typeid); + } + } else { + calculationStore.setStatus( + 'radioRequirementTelematic', + ElementStatus.Disabled, + ); + } + }, + }), + + (calculationStore, calculationProcess) => ({ + expression: () => { + return calculationStore.getValue('requirementTelematic'); + }, + effect: requirementTelematic => { + if (calculationProcess.hasProcess(Process.LoadKp)) { + return; + } + const recalcWithRevision = calculationStore.getValue( + 'recalcWithRevision', + ); + if (!recalcWithRevision) { + calculationStore.setValue('telematic', null); + + const addProducts = calculationStore.getStaticData( + 'evo_addproduct_type', + ); + let tracker = addProducts.find(x => + x.evo_controls_program?.includes(requirementTelematic), + ); + + calculationStore.setValue('tracker', tracker?.evo_addproduct_typeid); + } else { + calculationStore.setStatus( + 'radioRequirementTelematic', + ElementStatus.Disabled, + ); } }, options: { @@ -368,6 +462,11 @@ const reactionEffects: IReactionEffect[] = [ }), ]; +const map_add_product_types_to_values = { + tracker: 100000003, + telematics: 100000004, +}; + const elementsToDisable: (ElementsNames | TableNames)[] = [ 'tablePayments', 'selectLead', @@ -405,6 +504,7 @@ const elementsToDisable: (ElementsNames | TableNames)[] = [ 'selectTelematic', 'selectTracker', 'tbxMileage', + 'selectSubsidy', ]; export default reactionEffects; diff --git a/src/client/stores/CalculationStore/Effects/reactions/requestReactions.ts b/src/client/stores/CalculationStore/Effects/reactions/requestReactions.ts index 83ee17d..1247d80 100644 --- a/src/client/stores/CalculationStore/Effects/reactions/requestReactions.ts +++ b/src/client/stores/CalculationStore/Effects/reactions/requestReactions.ts @@ -567,7 +567,7 @@ export default [ CrmService.crmgqlquery({ query: gql` query($statecode: Int, $salonaccountid: Uuid!) { - account: salon_providers( + selectDealerPerson: salon_providers( statecode: $statecode salonaccountid: $salonaccountid ) { @@ -575,27 +575,27 @@ export default [ name evo_broker_accountid evo_kpp + evo_inn } } `, - toOptions: ['account'], + toOptions: ['selectDealerPerson'], variables: { salonaccountid: dealerId, statecode: 0, }, }).then(({ entities }) => { + // @ts-ignore + const dealerPersons = entities.selectDealerPerson; if ( - entities.account && - Array.isArray(entities.account) && - entities.account.length > 0 + dealerPersons && + Array.isArray(dealerPersons) && + dealerPersons.length > 0 ) { - calculationStore.setOptions( - 'selectDealerPerson', - entities.account, - ); + calculationStore.setOptions('selectDealerPerson', dealerPersons); calculationStore.setValue( 'dealerPerson', - entities.account[0].accountid, + dealerPersons[0].accountid, ); calculationStore.setStatus( 'selectDealerPerson', @@ -821,6 +821,10 @@ export default [ evo_impairment_groupid evo_vehicle_type evo_gps + evo_vehicle_body_typeidData { + evo_id_elt + } + evo_running_gear } } `, diff --git a/src/client/stores/CalculationStore/config/initialFilters.ts b/src/client/stores/CalculationStore/config/initialFilters.ts index 6b7dc45..a84cd75 100644 --- a/src/client/stores/CalculationStore/config/initialFilters.ts +++ b/src/client/stores/CalculationStore/config/initialFilters.ts @@ -1,6 +1,14 @@ +import { + ElementsNames, + TElements, +} from 'core/types/Calculation/Store/elements'; import { TElementFilter } from 'core/types/Calculation/Store/filters'; -import { TElements } from 'core/types/Calculation/Store/elements'; const initialFilters: TElements = {}; +export const noResetValueElements: ElementsNames[] = [ + 'selectTechnicalCard', + 'selectFuelCard', +]; + export default initialFilters; diff --git a/src/client/stores/CalculationStore/config/initialOptions.ts b/src/client/stores/CalculationStore/config/initialOptions.ts index 89a7300..b4326f9 100644 --- a/src/client/stores/CalculationStore/config/initialOptions.ts +++ b/src/client/stores/CalculationStore/config/initialOptions.ts @@ -273,6 +273,30 @@ const initialOptions: TElements = { 'Для экскурсионных перевозок в т.ч. на торжества; трансфер в аэропорт и пр.', value: 100000013, }, + { + name: 'Дорожно-строительная техника', + value: 100000014, + }, + { + name: 'Жилищно-коммунальное хозяйство', + value: 100000015, + }, + { + name: 'Лесное хозяйство', + value: 100000016, + }, + { + name: 'Подъёмно-транспортная отрасль', + value: 100000017, + }, + { + name: 'Сельское хозяйство', + value: 100000018, + }, + { + name: 'Строительство', + value: 100000019, + }, ], objectUseFor => objectUseFor.name.toLowerCase(), ['asc'], @@ -312,6 +336,10 @@ const initialOptions: TElements = { ], radioRequirementTelematic: [ + { + name: 'Не требуется', + value: 100000004, + }, { name: 'START', value: 100000000, @@ -320,14 +348,26 @@ const initialOptions: TElements = { name: 'START+', value: 100000001, }, - // { - // name: 'COMFORT', - // value: 100000002, - // }, + { + name: 'COMFORT', + value: 100000002, + }, { name: 'COMFORT+', value: 100000003, }, + { + name: 'Omnicomm_1', + value: 100000005, + }, + { + name: 'Omnicomm_2', + value: 100000006, + }, + { + name: 'Omnicomm_3', + value: 100000007, + }, ], radioCalcType: [ { @@ -336,7 +376,7 @@ const initialOptions: TElements = { }, { name: 'Суммы', - value: 100000002, + value: 100000001, }, ], radioObjectRegistration: [ diff --git a/src/client/stores/CalculationStore/config/initialValues.ts b/src/client/stores/CalculationStore/config/initialValues.ts index 685f26e..5c70f51 100644 --- a/src/client/stores/CalculationStore/config/initialValues.ts +++ b/src/client/stores/CalculationStore/config/initialValues.ts @@ -60,8 +60,8 @@ const initialValues: TValues = { insKaskoType: 100000000, insDecentral: false, insUnlimitDrivers: true, - insAgeDrivers: 18, - insExpDrivers: 18, + // insAgeDrivers: 18, + // insExpDrivers: 1, lastPaymentRedemption: true, priceWithDiscount: false, fullPriceWithDiscount: false, diff --git a/src/client/stores/CalculationStore/subStores/eltStore.ts b/src/client/stores/CalculationStore/subStores/eltStore.ts index 883fab5..54b8b0e 100644 --- a/src/client/stores/CalculationStore/subStores/eltStore.ts +++ b/src/client/stores/CalculationStore/subStores/eltStore.ts @@ -1,6 +1,7 @@ // @ts-nocheck import { initFields } from 'client/Components/Calculation/ELT/Content/lib/resetIns'; -import { makeAutoObservable } from 'mobx'; +import { isEqual } from 'lodash'; +import { makeAutoObservable, toJS } from 'mobx'; const ELTStore = makeAutoObservable( Object.assign( @@ -8,8 +9,8 @@ const ELTStore = makeAutoObservable( ...['osago', 'kasko'].map(x => ({ [x]: { isReseted() { - return this.list.every( - x => Object.keys(x).length === initFields.length, + return this.list.every(x => + isEqual(Object.keys(toJS(x)), initFields), ); }, reset(list) { @@ -34,7 +35,7 @@ const ELTStore = makeAutoObservable( }, addToCompanyRes(insType, index, res) { const companyData = this[insType].list[index]; - this[insType].list[index] = { ...companyData, ...res }; + this[insType].list[index] = Object.assign(companyData, res); }, }, ), diff --git a/src/core/services/CalculationService/index.ts b/src/core/services/CalculationService/index.ts index 10e3464..95fe4be 100644 --- a/src/core/services/CalculationService/index.ts +++ b/src/core/services/CalculationService/index.ts @@ -13,7 +13,6 @@ export default class { String.prototype.concat( CORE_PROXY_URL, '/api', - '/v1', '/calculation', '/calculate', ), diff --git a/src/core/services/CrmService/propsMap.ts b/src/core/services/CrmService/propsMap.ts index baee9ab..1567b29 100644 --- a/src/core/services/CrmService/propsMap.ts +++ b/src/core/services/CrmService/propsMap.ts @@ -7,7 +7,14 @@ const propsMap: TEntities<{ getName?: (entity: TCRMEntity, targetName: string) => string | undefined; }> = { account: { - getName: account => `${account.name} ${account.evo_kpp || ''}`, + getName: (account, targetName) => { + if (['selectDealerPerson'].includes(targetName)) { + return ` + ${account.name} + ${account.evo_inn || '-'} / ${account.evo_kpp || '-'}`; + } + return `${account.name} ${account.evo_kpp || ''}`; + }, value: 'accountid', }, lead: { @@ -124,6 +131,10 @@ const propsMap: TEntities<{ name: 'evo_name', value: 'evo_id', }, + evo_subsidy: { + name: 'evo_name', + value: 'evo_subsidyid', + }, }; export default propsMap; diff --git a/src/core/types/Calculation/Prepare.ts b/src/core/types/Calculation/Prepare.ts index 26f878a..029a0c6 100644 --- a/src/core/types/Calculation/Prepare.ts +++ b/src/core/types/Calculation/Prepare.ts @@ -91,6 +91,12 @@ export interface PreparedValues { dogCreditLeasing?: number; tlmCostPaymentSum?: number; gpsCostPaymentSum?: number; + directorBonusNsib?: number; + regionalDirectorBonusNsib?: number; + loanRatePeriod?: number; + subsidySum?: number; + subsidyPaymentNumber?: number; + fuelCardSum?: number; } export interface PaymentRow { diff --git a/src/core/types/Calculation/Requests.ts b/src/core/types/Calculation/Requests.ts index 1cb884a..7de7477 100644 --- a/src/core/types/Calculation/Requests.ts +++ b/src/core/types/Calculation/Requests.ts @@ -12,7 +12,7 @@ import { CRMEntityNames } from 'core/types/Entities/crmEntityNames'; export interface IQueryToCRMGQL { query: any; toOptions?: CRMEntityNames[] | ElementsNames[]; - variables: { + variables?: { [prop in keyof TCRMEntity]: any; } & { [prop: string]: any }; } diff --git a/src/core/types/Calculation/Store/effect.ts b/src/core/types/Calculation/Store/effect.ts index ce619c7..1e493c8 100644 --- a/src/core/types/Calculation/Store/effect.ts +++ b/src/core/types/Calculation/Store/effect.ts @@ -19,7 +19,7 @@ export interface IReactionEffect { ): { expression: (r: IReactionPublic) => any; effect: (arg: any, prev: any, r: IReactionPublic) => void; - options?: IReactionOptions; + options?: IReactionOptions; }; } diff --git a/src/core/types/Calculation/Store/elements.ts b/src/core/types/Calculation/Store/elements.ts index 871fa14..0063a3d 100644 --- a/src/core/types/Calculation/Store/elements.ts +++ b/src/core/types/Calculation/Store/elements.ts @@ -145,7 +145,10 @@ export type ElementsNames = | 'radioTypePTS' | 'labelRegistrationDescription' | 'selectLegalClientRegion' - | 'selectLegalClientTown'; + | 'selectLegalClientTown' + | 'selectSubsidy' + | 'labelSubsidySum' + | 'selectFuelCard'; export type LinkElementsNames = 'linkDownloadKp'; diff --git a/src/core/types/Calculation/Store/index.ts b/src/core/types/Calculation/Store/index.ts index b7e7efe..5fd6772 100644 --- a/src/core/types/Calculation/Store/index.ts +++ b/src/core/types/Calculation/Store/index.ts @@ -15,7 +15,6 @@ import { TableNames, TableProps, TableValuesNames, - TCellCallback, } from './tables'; import { ResultValuesNames, TValue, TValues, ValuesNames } from './values'; @@ -47,7 +46,7 @@ interface ICalculationValues { applyOptions: (options: TElements<(IBaseOption & TCRMEntity)[]>) => void; filters: TElements; - getFilter: (elementName: ElementsNames) => TElementFilter; + getFilter: (elementName: ElementsNames) => TElementFilter | undefined; setFilter: ( elementName: ElementsNames, filter: TElementFilter | undefined, @@ -61,11 +60,12 @@ interface ICalculationValues { sourceValueName: ValuesNames | ResultValuesNames, newValue: TValue, ) => void; - setValues: (values: TValues) => void; + setValues: (values: TValues, override?: boolean) => void; statuses: TElements; getStatus: (elementName: ElementsNames) => ElementStatus; setStatus: (elementName: ElementsNames, status: ElementStatus) => void; + setStatuses: (statuses: TElements, override?: boolean) => void; validations: TElements; getValidation: (elementName: ElementsNames) => boolean; @@ -111,10 +111,8 @@ interface ICalculationTables { override?: boolean, ) => ({ options, - callbacks, }: { options?: TableProps<(IBaseOption & TCRMEntity)[]>; - callbacks?: TableProps; }) => void; } diff --git a/src/core/types/Calculation/Store/links.ts b/src/core/types/Calculation/Store/links.ts index 3acea3e..eaa726e 100644 --- a/src/core/types/Calculation/Store/links.ts +++ b/src/core/types/Calculation/Store/links.ts @@ -1 +1 @@ -export type LinksNames = 'kpUrl'; +export type LinksNames = 'kpUrl' | 'leadUrl' | 'opportunityUrl' | 'quoteUrl'; diff --git a/src/core/types/Calculation/Store/process.ts b/src/core/types/Calculation/Store/process.ts index 25f33eb..6003fb0 100644 --- a/src/core/types/Calculation/Store/process.ts +++ b/src/core/types/Calculation/Store/process.ts @@ -1,4 +1,5 @@ export enum Process { + Init, LoadKp, RecalcWithoutRevision, ELT, diff --git a/src/core/types/Calculation/Store/tables.ts b/src/core/types/Calculation/Store/tables.ts index 26c7e59..e713cc8 100644 --- a/src/core/types/Calculation/Store/tables.ts +++ b/src/core/types/Calculation/Store/tables.ts @@ -51,9 +51,7 @@ export type TableColumn = { }; export type TableColumnFeatures = { - numerize?: { - columnTitle?: string; - }; + [feature: string]: any; }; export type TableParams = { diff --git a/src/core/types/Calculation/Store/values.ts b/src/core/types/Calculation/Store/values.ts index a30b7b3..99680c4 100644 --- a/src/core/types/Calculation/Store/values.ts +++ b/src/core/types/Calculation/Store/values.ts @@ -131,11 +131,12 @@ export type ValuesNames = | 'objectTypeTax' | 'typePTS' | 'legalClientRegion' - | 'legalClientTown'; + | 'legalClientTown' + | 'subsidy' + | 'subsidySum' + | 'fuelCard'; export type ComputedValuesNames = - | 'leadName' - | 'opportunityName' | 'leaseObjectRiskName' | 'insKaskoPriceLeasePeriod' | 'irrInfo' @@ -163,7 +164,7 @@ type SuitTuple = typeof resultsValues; export type ResultValuesNames = SuitTuple[number]; export type TValues = { - [valueName in ValuesNames | ResultValuesNames]?: T; + [valueName in ValuesNames | ResultValuesNames | ComputedValuesNames]?: T; }; export type TValue = any; diff --git a/src/core/types/Calculation/components.ts b/src/core/types/Calculation/components.ts index 8e6a5cb..8b6f658 100644 --- a/src/core/types/Calculation/components.ts +++ b/src/core/types/Calculation/components.ts @@ -1,9 +1,9 @@ -import React from 'react'; +import { FC } from 'react'; import { AllElements } from './Store/elements'; import { TableNames } from './Store/tables'; export type ElementProps = { [key: string]: any }; -export type Component = React.FC; +export type Component = FC; interface IBlock { title?: string; diff --git a/src/core/types/Entities/crmEntities.ts b/src/core/types/Entities/crmEntities.ts index 42d9f1f..8001258 100644 --- a/src/core/types/Entities/crmEntities.ts +++ b/src/core/types/Entities/crmEntities.ts @@ -18,6 +18,7 @@ export interface IAccount { evo_address_legalidData?: IEvoAddress; evo_id_elt?: string; evo_id_elt_osago?: string; + evo_legal_region_calc?: boolean; } export interface IEvoAddress { @@ -39,6 +40,7 @@ export interface ILead { accountidData?: IAccount; owner_domainname?: string; evo_inn?: string; + link?: string; } export interface IOpportunity { @@ -51,6 +53,7 @@ export interface IOpportunity { accountidData?: IAccount; parentaccountid?: string; evo_addproduct_types?: IEvoAddproductType[]; + link?: string; } export interface IQuote { @@ -94,6 +97,11 @@ export interface IQuote { evo_franchise?: string; evo_id_elt_osago?: string; evo_object_registration?: number; + link?: string; + evo_accept_control_addproduct_typeid?: string; + evo_req_telematic?: number; + evo_req_telematic_accept?: number; + evo_one_year_insurance?: boolean; } export interface IEvoGraph { @@ -147,10 +155,10 @@ export interface IEvoLeasingObjectType { evo_vehicle_type_tax?: number; evo_vehicle_type?: number[]; } - export interface IEvoBrand { evo_name?: string; evo_brandid?: string; + evo_brand_owner?: number; evo_importer_reward_perc?: number; evo_importer_reward_rub?: number; statecode?: number; @@ -169,6 +177,10 @@ export interface IEvoModel { evo_baseproduct?: any; evo_vehicle_type?: number; evo_gps?: boolean; + evo_vehicle_body_typeidData?: { + evo_id_elt: string; + }; + evo_running_gear?: number; } export interface IEvoEquipment { @@ -361,9 +373,11 @@ export interface IEvoTarif { evo_models?: IEvoModel[]; evo_model_exceptions?: IEvoModel[]; evo_rates?: IEvoRate[]; + evo_delivery_time?: number[]; } export interface IEvoRate { + createdon?: Date; evo_id?: string; evo_name?: string; evo_rateid?: string; @@ -377,6 +391,8 @@ export interface IEvoRate { evo_dateto?: Date; statecode?: number; evo_brands?: IEvoBrand[]; + evo_credit_period?: number; + evo_tarifs?: IEvoTarif[]; } export interface IEvoPlanPayment { @@ -413,6 +429,17 @@ export interface IEvoJobTitle { evo_job_titleid?: string; } +export interface IEvoSubsidy { + evo_subsidy_summ?: number; + evo_percent_subsidy?: number; + evo_max_subsidy_summ?: number; + evo_subsidyid?: string; + evo_get_subsidy_payment?: number; + evo_brands?: IEvoBrand[]; + evo_models?: IEvoModel[]; + accounts?: IAccount[]; +} + type BaseEntity = { __typename?: CRMEntityNames; }; @@ -449,4 +476,5 @@ export type TCRMEntity = BaseEntity & IEvoPlanPayment & ISystemUser & IEvoJobTitle & - IEvoSotCoefficientType; + IEvoSotCoefficientType & + IEvoSubsidy; diff --git a/src/core/types/Entities/crmEntityNames.ts b/src/core/types/Entities/crmEntityNames.ts index be07889..17391c0 100644 --- a/src/core/types/Entities/crmEntityNames.ts +++ b/src/core/types/Entities/crmEntityNames.ts @@ -28,7 +28,8 @@ export type CRMEntityNames = | 'evo_rate' | 'evo_planpayment' | 'systemuser' - | 'evo_sot_coefficient_type'; + | 'evo_sot_coefficient_type' + | 'evo_subsidy'; //TODO: or string export type TEntities = { diff --git a/src/core/validation/validate.ts b/src/core/validation/validate.ts index 549c120..a59ed31 100644 --- a/src/core/validation/validate.ts +++ b/src/core/validation/validate.ts @@ -1,4 +1,5 @@ import { getValueName } from 'client/Containers/Calculation/lib/elements/tools'; +import { openNotification } from 'client/Elements/Notification'; import { ElementsNames, TElements, @@ -39,3 +40,32 @@ export const getValue = ( }; export const convertToValidationResult = result => ({ isValid: !result }); + +export function showValidationMessages( + validationsResult: TElements, + title: string, +): { hasMessages: boolean } { + let messages: string[] = []; + (Object.keys(validationsResult) as ElementsNames[]).forEach(elementName => { + const elementValidationResult = validationsResult[elementName]; + if (elementValidationResult) { + const { isValid, message } = elementValidationResult; + if (isValid === false && message !== undefined) { + messages.push(message); + } + } + }); + + const hasMessages = messages?.length > 0; + if (hasMessages) { + messages.forEach(message => { + if (message) + openNotification({ + type: 'error', + title, + description: message, + })(); + }); + } + return { hasMessages }; +}