Merge branch 'development'

This commit is contained in:
Chika 2021-12-16 10:07:42 +03:00
commit 1ab975c226
81 changed files with 1720 additions and 669 deletions

View File

@ -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'],
],
},
};

View File

@ -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",

View File

@ -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 }) => {
></AntTable>
</TableWrapper>
);
}) as React.FC<ITableProps>;
}) as FC<ITableProps>;

View File

@ -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,

View File

@ -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 {

View File

@ -22,12 +22,22 @@ export const requiredFields: ElementsNames[] = [
export const conditions: TElements<ValidationCondition> = {
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<ValidationCondition> = {
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<ValidationCondition> = {
isValid: true,
};
},
cbxInsDecentral: calculationStore => {
const insDecentral = calculationStore.getValue('insDecentral');
if (insDecentral) {
return {
isValid: false,
message: 'Децентрализованное страхование не может быть расчитано в ЭЛТ',
};
}
return {
isValid: true,
};
},
};
export const resetFields: ElementsNames[] = [

View File

@ -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: 'Москва',

View File

@ -22,7 +22,7 @@ export const requiredFields: ElementsNames[] = [
'radioInfuranceOPF',
];
const conditions: TElements<ValidationCondition> = {
const osagoConditions: TElements<ValidationCondition> = {
selectTownRegistration: calculationStore => {
const objectRegistration = calculationStore.getValue('objectRegistration');
if (objectRegistration === 100000001) {
@ -40,6 +40,11 @@ const conditions: TElements<ValidationCondition> = {
},
};
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,
};

View File

@ -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<void>((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();
});
});
},

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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 {

View File

@ -2,7 +2,12 @@ import { Result } from 'antd';
export default {
404: () => <Result status="404" title="404" subTitle="Ой! Тут ничего нет." />,
500: () => (
<Result status="500" title="" subTitle={'Ой! Что-то сломалось.'} />
500: props => (
<Result
status="500"
title=""
subTitle={'Ой! Что-то сломалось.'}
{...props}
/>
),
};

View File

@ -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 => (
<Background {...props}>
<Flex flexDirection="column">
{renderGroups({ groups: calculationResults })}
</Flex>
{renderSections({ sectionsList: calculationResults })}
</Background>
);

View File

@ -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',
],
},
],
},
],

View File

@ -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 => (
<Background {...props}>
<Flex flexDirection="column">{renderGroups({ groups: resultsTable })}</Flex>
</Background>
);
export default Results;

View File

@ -1,13 +0,0 @@
import { IGroup } from 'core/types/Calculation/components';
export const resultsTable: IGroup[] = [
{
style: { columnsNumber: 1 },
blocks: [
{
title: 'График платежей',
elements: ['tableResults'],
},
],
},
];

View File

@ -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'],
},
],
},

View File

@ -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 = () => (
<Flex flexDirection="column" width={['100vw', '100vw', '100%']}>
<Info />
<Results />
</Flex>
);
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 <ServerError />;
return (
<ServerError
extra={[<Button text="Попробовать еще раз" action={fetch}></Button>]}
/>
);
}
return (
<Grid>
<Sections width={['100vw', '100vw', '100%']} />
<Middle />
<ResultsTable minHeight="500px" width={['100vw', '100vw', '100%']} />
<Info width={['100vw', '100vw', '100%']} />
<Results minHeight="500px" width={['100vw', '100vw', '100%']} />
</Grid>
);
};

View File

@ -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: {

View File

@ -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<Component> = {
labelResultBonusMPL: Label,
labelResultDopMPLLeasing: Label,
labelResultBonusDopProd: Label,
linkDownloadKp: Download,
linkDownloadKp: Link,
tbxMileage: InputNumber,
radioCalcType: Radio,
tbxTotalPayments: InputNumber,
@ -171,6 +171,9 @@ const elementsComponents: TElements<Component> = {
labelRegistrationDescription: Label,
selectLegalClientRegion: Select,
selectLegalClientTown: Select,
selectSubsidy: Select,
selectFuelCard: Select,
labelSubsidySum: Label,
};
const tablesComponents: StoreTables<Component> = {

View File

@ -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<ElementProps> = {
tbxFirstPaymentPerc: {
min: '0',
max: '50',
precision: 2,
precision: 4,
formatter: formatNumber,
},
tbxFirstPaymentRub: {
@ -217,45 +220,45 @@ const elementsProps: TElements<ElementProps> = {
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<ElementProps> = {
showSearch: true,
},
radioRequirementTelematic: {
style: 'button',
// style: 'button',
},
radioQuoteContactGender: {
style: 'button',
@ -313,21 +316,47 @@ const elementsProps: TElements<ElementProps> = {
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<ElementProps> = {
max: 9999999,
precision: 2,
tooltip: {
title: 'Без учета налога на роскошь',
placement: 'topLeft',
Component: buildTooltip({
title: 'Без учета налога на роскошь',
placement: 'topLeft',
}),
},
},
tbxVehicleTaxInLeasingPeriod: {
@ -401,7 +432,7 @@ const elementsProps: TElements<ElementProps> = {
// },
},
tableInsurance: {
tag: {
sub: {
Component: InsuranceTag,
},
},
@ -421,7 +452,7 @@ const elementsProps: TElements<ElementProps> = {
},
};
const resultElementsProps: TElements<ElementProps> = Object.assign(
const labelElementsProps: TElements<ElementProps> = Object.assign(
{},
[
'labelResultTotalGraphwithNDS',
@ -436,6 +467,7 @@ const resultElementsProps: TElements<ElementProps> = Object.assign(
'labelResultBonusMPL',
'labelResultDopMPLLeasing',
'labelResultBonusDopProd',
'labelSubsidySum',
].reduce(
(ac, a) => ({
...ac,
@ -457,4 +489,4 @@ const resultElementsProps: TElements<ElementProps> = Object.assign(
{},
),
);
export default Object.assign(elementsProps, resultElementsProps);
export default Object.assign(elementsProps, labelElementsProps);

View File

@ -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,
},
};

View File

@ -37,9 +37,7 @@ const columns: TableColumn[] = [
];
const features: TableColumnFeatures = {
numerize: {
columnTitle: 'Номер',
},
numerize: true,
};
const params = { features };

View File

@ -136,6 +136,9 @@ export const elementsTitles: TElements<string> = {
tbxINNForCalc: 'ИНН контрагента',
selectLegalClientRegion: 'Регион по юр.адресу клиента',
selectLegalClientTown: 'Город по юр.адресу клиента',
selectSubsidy: 'Субсидия',
labelSubsidySum: 'Сумма субсидии с НДС',
selectFuelCard: 'Топливная карта',
};
const resultsTitles: TElements<string> = {

View File

@ -135,6 +135,9 @@ export const elementsValues: TElements<ValuesNames> = {
radioTypePTS: 'typePTS',
selectLegalClientRegion: 'legalClientRegion',
selectLegalClientTown: 'legalClientTown',
selectSubsidy: 'subsidy',
labelSubsidySum: 'subsidySum',
selectFuelCard: 'fuelCard',
};
const resultElementsValues: TElements<ResultValuesNames> = {

View File

@ -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();
},
)

View File

@ -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
}
}
`;

View File

@ -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 {

View File

@ -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
}
}
`;

View File

@ -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
}
}
`;

View File

@ -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 (
<Flex
flexDirection={['column', 'row']}
justifyContent={[undefined, 'space-between']}
alignItems={[undefined, 'center']}
>
<ElementTitle {...style}>{elementTitle}</ElementTitle>
<sub.Component />
</Flex>
);
}
return <ElementTitle {...style}>{elementTitle}</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 (
<Tooltip {...tooltip}>
<Flex flexDirection="column" key={ie}>
<Flex
flexDirection={['column', 'row']}
justifyContent={[undefined, 'space-between']}
alignItems={[undefined, 'center']}
>
<ElementTitle>{elementTitle}</ElementTitle>
<TagComponent />
</Flex>
<Component />
</Flex>
</Tooltip>
const Tooltip = tooltip?.Component;
const element = (
<Flex flexDirection="column" key={ie}>
<Head
sub={sub}
elementTitle={elementTitle}
style={elementStyle?.head}
/>
<Component />
</Flex>
);
if (tooltip) {
return <Tooltip>{element}</Tooltip>;
}
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 (
<Fragment key={ib}>
<Flex flexDirection="column" flexWrap="nowrap">
{title && <SecondaryColoredText>{title}</SecondaryColoredText>}
{renderElements({ elements })}
</Flex>
</Fragment>
<Flex key={ib} flexDirection="column" flexWrap="nowrap">
{title && <SecondaryColoredText>{title}</SecondaryColoredText>}
<ElementsGrid {...style} defaultColumnsNumber={1}>
{renderElements({ elements, elementStyle })}
</ElementsGrid>
</Flex>
);
});
};
@ -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 (
<Box key={ig} my="5px">
{title && <BlocksTitle>{title}</BlocksTitle>}
<BlocksGrid {...style}>{renderBlocks({ blocks })}</BlocksGrid>
<ElementsGrid {...style} defaultColumnsNumber={2}>
{renderBlocks({ blocks })}
</ElementsGrid>
</Box>
);
});
@ -103,7 +115,7 @@ export const renderGroups = ({ groups }) => {
export const renderSections = ({ sectionsList }) => {
return (
<Tabs type="line">
<Tabs type="line" tabBarGutter="22px">
{sectionsList.map((section, is) => {
const { title, groups } = section;
return (

View File

@ -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 (
<AntButton
{...props}
@ -10,11 +10,11 @@ const Download = ({ status, url, text, icon: Icon, ...props }) => {
href={url}
disabled={status === ElementStatus.Disabled || !url}
loading={status === ElementStatus.Loading}
icon={<Icon />}
icon={Icon && <Icon />}
>
{text}
</AntButton>
);
};
export default Download;
export default Link;

View File

@ -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 () => (
<thead>
<tr>
{features?.numerize && <th>{features.numerize.columnTitle || '#'}</th>}
{columns.map(column => (
<th key={column.name}>{column.title}</th>
))}
</tr>
</thead>
);
}
function buildBody(
tableName,
features,
rows,
columnsProps,
withTableValue,
partNumber,
rowsNumber,
) {
return () => (
<tbody>
{rows.map((row, rowIndex) => {
const partRowIndex = rowIndex + partNumber * rowsNumber;
return (
<tr key={row.name}>
{features?.numerize && <td>{partRowIndex + 1}</td>}
{Object.keys(row).map(propName => {
const CellComponent = columnsProps[propName].Component;
const Cell = withTableValue(CellComponent)({
tableName,
rowIndex: partRowIndex,
propName,
...columnsProps[propName].props,
});
return (
<td key={propName}>
<Cell />
</td>
);
})}
</tr>
);
})}
</tbody>
);
}
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 (
<TableWrapper>
<table>
<thead>
<tr>
{features && features.numerize && (
<th>{features.numerize.columnTitle || '#'}</th>
)}
{columns.map(({ title }, ci) => {
return <th key={ci}>{title}</th>;
})}
</tr>
</thead>
<tbody>
{rows.map((row, ri) => {
const rowProps = Object.keys(row);
return (
<tr key={ri}>
{features && features.numerize && <td>{ri + 1}</td>}
{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 (
<td key={ki}>
<Element />
</td>
);
})}
</tr>
);
})}
</tbody>
</table>
</TableWrapper>
);
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(
<TableStyles key={partNumber.toString()}>
<table>
<Head />
<Body />
</table>
</TableStyles>,
);
}
return tables;
}, [rows.length]);
return <TablesGrid split={features?.split}>{tables}</TablesGrid>;
};
export default Table;

View File

@ -1,3 +1,5 @@
import { Tooltip as AntTooltip } from 'antd';
export default AntTooltip;
export default params => props => (
<AntTooltip {...params}>{props.children}</AntTooltip>
);

View File

@ -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({

View File

@ -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 };
};

View File

@ -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,

View File

@ -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]);

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -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 &&

View File

@ -15,15 +15,30 @@ export default {
const results: TableProps<ITableCell>[] = [];
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),
);
},
};

View File

@ -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<ValidationCondition> = {
selectLeaseObjectCategory: calculationStore => {
@ -78,6 +81,105 @@ const customConditions: TElements<ValidationCondition> = {
}
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<any> = {
@ -91,7 +193,6 @@ const elementsValidations: TElements<any> = {
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<ValidationCondition>, 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, 'Ошибка во время расчета графика');
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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
`;

View File

@ -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;
}

View File

@ -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] });

View File

@ -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(

View File

@ -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,
];

View File

@ -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),
),
);
},
}),

View File

@ -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[];

View File

@ -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);
}

View File

@ -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<string> = {
const mapKPtoValues: TValues<keyof IQuote | string> = {
product: 'evo_baseproductid',
clientType: 'evo_client_typeid',
leaseObjectPrice: 'evo_supplier_currency_price',
@ -53,10 +53,10 @@ const mapKPtoValues: TValues<string> = {
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<string> = {
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) {

View File

@ -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

View File

@ -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
}
}
`;

View File

@ -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;

View File

@ -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;

View File

@ -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
}
}
`,

View File

@ -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<TElementFilter> = {};
export const noResetValueElements: ElementsNames[] = [
'selectTechnicalCard',
'selectFuelCard',
];
export default initialFilters;

View File

@ -273,6 +273,30 @@ const initialOptions: TElements<IBaseOption[]> = {
'Для экскурсионных перевозок в т.ч. на торжества; трансфер в аэропорт и пр.',
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<IBaseOption[]> = {
],
radioRequirementTelematic: [
{
name: 'Не требуется',
value: 100000004,
},
{
name: 'START',
value: 100000000,
@ -320,14 +348,26 @@ const initialOptions: TElements<IBaseOption[]> = {
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<IBaseOption[]> = {
},
{
name: 'Суммы',
value: 100000002,
value: 100000001,
},
],
radioObjectRegistration: [

View File

@ -60,8 +60,8 @@ const initialValues: TValues<TValue> = {
insKaskoType: 100000000,
insDecentral: false,
insUnlimitDrivers: true,
insAgeDrivers: 18,
insExpDrivers: 18,
// insAgeDrivers: 18,
// insExpDrivers: 1,
lastPaymentRedemption: true,
priceWithDiscount: false,
fullPriceWithDiscount: false,

View File

@ -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);
},
},
),

View File

@ -13,7 +13,6 @@ export default class {
String.prototype.concat(
CORE_PROXY_URL,
'/api',
'/v1',
'/calculation',
'/calculate',
),

View File

@ -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;

View File

@ -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 {

View File

@ -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 };
}

View File

@ -19,7 +19,7 @@ export interface IReactionEffect {
): {
expression: (r: IReactionPublic) => any;
effect: (arg: any, prev: any, r: IReactionPublic) => void;
options?: IReactionOptions;
options?: IReactionOptions<any>;
};
}

View File

@ -145,7 +145,10 @@ export type ElementsNames =
| 'radioTypePTS'
| 'labelRegistrationDescription'
| 'selectLegalClientRegion'
| 'selectLegalClientTown';
| 'selectLegalClientTown'
| 'selectSubsidy'
| 'labelSubsidySum'
| 'selectFuelCard';
export type LinkElementsNames = 'linkDownloadKp';

View File

@ -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<TElementFilter>;
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<any>) => void;
setValues: (values: TValues<any>, override?: boolean) => void;
statuses: TElements<ElementStatus>;
getStatus: (elementName: ElementsNames) => ElementStatus;
setStatus: (elementName: ElementsNames, status: ElementStatus) => void;
setStatuses: (statuses: TElements<ElementStatus>, override?: boolean) => void;
validations: TElements<boolean>;
getValidation: (elementName: ElementsNames) => boolean;
@ -111,10 +111,8 @@ interface ICalculationTables {
override?: boolean,
) => ({
options,
callbacks,
}: {
options?: TableProps<(IBaseOption & TCRMEntity)[]>;
callbacks?: TableProps<TCellCallback>;
}) => void;
}

View File

@ -1 +1 @@
export type LinksNames = 'kpUrl';
export type LinksNames = 'kpUrl' | 'leadUrl' | 'opportunityUrl' | 'quoteUrl';

View File

@ -1,4 +1,5 @@
export enum Process {
Init,
LoadKp,
RecalcWithoutRevision,
ELT,

View File

@ -51,9 +51,7 @@ export type TableColumn = {
};
export type TableColumnFeatures = {
numerize?: {
columnTitle?: string;
};
[feature: string]: any;
};
export type TableParams = {

View File

@ -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<T> = {
[valueName in ValuesNames | ResultValuesNames]?: T;
[valueName in ValuesNames | ResultValuesNames | ComputedValuesNames]?: T;
};
export type TValue = any;

View File

@ -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<any>;
export type Component = FC<any>;
interface IBlock {
title?: string;

View File

@ -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;

View File

@ -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<T> = {

View File

@ -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<ValidationResult>,
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 };
}