merge elt-connect

This commit is contained in:
vchikalkin 2021-05-18 10:32:52 +03:00
parent 9cf409df2c
commit 12f0bf2d8d
67 changed files with 1504 additions and 127 deletions

16
.storybook/main.js Normal file
View File

@ -0,0 +1,16 @@
module.exports = {
stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
{
name: '@storybook/preset-create-react-app',
options: {
craOverrides: {
fileLoaderExcludes: ['less'],
},
},
},
'@storybook/preset-ant-design',
],
};

10
.storybook/preview.js Normal file
View File

@ -0,0 +1,10 @@
export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
}

View File

@ -20,5 +20,6 @@
"source.organizeImports": true, "source.organizeImports": true,
"source.fixAll": true "source.fixAll": true
}, },
"editor.formatOnSave": true "editor.formatOnSave": true,
"workbench.editor.labelFormat": "short"
} }

View File

@ -4,13 +4,11 @@
"dependencies": { "dependencies": {
"@ant-design/icons": "^4.6.2", "@ant-design/icons": "^4.6.2",
"@apollo/client": "^3.3.13", "@apollo/client": "^3.3.13",
"@babel/code-frame": "^7.10.4",
"@babel/helper-split-export-declaration": "^7.11.0",
"@craco/craco": "^6.1.1", "@craco/craco": "^6.1.1",
"@testing-library/jest-dom": "^4.2.4", "@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^9.3.2", "@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^7.1.2", "@testing-library/user-event": "^12.1.10",
"antd": "^4.15.0", "antd": "^4.15.5",
"axios": "^0.21.1", "axios": "^0.21.1",
"babel-plugin-transform-imports": "^2.0.0", "babel-plugin-transform-imports": "^2.0.0",
"craco-antd": "^1.19.0", "craco-antd": "^1.19.0",
@ -33,30 +31,65 @@
"validator": "^13.5.2" "validator": "^13.5.2"
}, },
"devDependencies": { "devDependencies": {
"@storybook/addon-actions": "^6.2.9",
"@storybook/addon-essentials": "^6.2.9",
"@storybook/addon-links": "^6.2.9",
"@storybook/node-logger": "^6.2.9",
"@storybook/preset-ant-design": "^0.0.2",
"@storybook/preset-create-react-app": "^3.1.7",
"@storybook/react": "^6.2.9",
"@types/jest": "^26.0.15", "@types/jest": "^26.0.15",
"@types/lodash": "^4.14.168", "@types/lodash": "^4.14.168",
"@types/node": "^12.0.0",
"@types/pluralize": "^0.0.29", "@types/pluralize": "^0.0.29",
"@types/react": "^17.0.3", "@types/react": "^17.0.0",
"@types/react-dom": "^17.0.3", "@types/react-dom": "^17.0.0",
"@types/react-router-dom": "^5.1.7", "@types/react-router-dom": "^5.1.7",
"@types/rebass": "^4.0.8", "@types/rebass": "^4.0.8",
"@types/styled-components": "^5.1.9", "@types/styled-components": "^5.1.9",
"@types/uuid": "^8.3.0",
"commitizen": "^4.2.3", "commitizen": "^4.2.3",
"cz-conventional-changelog": "^3.3.0", "cz-conventional-changelog": "^3.3.0",
"source-map-explorer": "^2.5.2" "source-map-explorer": "^2.5.2"
}, },
"resolutions": {
"babel-loader": "8.1.0"
},
"scripts": { "scripts": {
"test": "craco test", "test": "react-scripts test",
"eject": "react-scripts eject", "eject": "react-scripts eject",
"start": "craco start", "start": "craco start",
"build": "craco build", "build": "craco build",
"eslint": "eslint ./src", "eslint": "eslint ./src",
"eslint:fix": "eslint ./src --fix", "eslint:fix": "eslint ./src --fix",
"commit": "git-cz", "commit": "git-cz",
"analyze": "source-map-explorer 'build/static/js/*.js'" "analyze": "source-map-explorer 'build/static/js/*.js'",
"storybook": "start-storybook -p 6006 -s public",
"build-storybook": "build-storybook -s public"
}, },
"eslintConfig": { "eslintConfig": {
"extends": "react-app" "extends": [
"react-app",
"react-app/jest"
],
"overrides": [
{
"files": [
"**/*.stories.*"
],
"rules": {
"import/no-anonymous-default-export": "off"
}
},
{
"files": [
"**/*.stories.*"
],
"rules": {
"import/no-anonymous-default-export": "off"
}
}
]
}, },
"browserslist": { "browserslist": {
"production": [ "production": [

View File

@ -1,11 +1,11 @@
import { ConfigProvider, message } from 'antd';
import ruRu from 'antd/es/locale/ru_RU';
import { StoreProvider } from 'client/contexts/storeContext'; import { StoreProvider } from 'client/contexts/storeContext';
import theme from 'client/UIKit/theme'; import theme from 'client/UIKit/theme';
import { BrowserRouter } from 'react-router-dom'; import { BrowserRouter } from 'react-router-dom';
import { ThemeProvider } from 'styled-components'; import { ThemeProvider } from 'styled-components';
import './App.less'; import './App.less';
import Layout from './Layout'; import Layout from './Layout';
import { ConfigProvider, message } from 'antd';
import ruRu from 'antd/es/locale/ru_RU';
message.config({ message.config({
top: 70, top: 70,

View File

@ -0,0 +1,74 @@
import Alert from 'client/Elements/Alert';
import { useStores } from 'client/hooks/useStores';
import { useEffect, useState } from 'react';
import { getFieldsNames, validate } from '../lib/validation';
import InsTable from './InsTable';
import Controls from './TableControls';
export default ({
title,
insType,
getData,
onSelectRow,
requiredFields,
...tableProps
}) => props => {
const { calculationStore } = useStores();
const { ELTStore } = calculationStore.stores;
const [selectedKey, selectKey] = useState('');
const [alert, setAlert] = useState({
message: undefined,
type: undefined,
});
const [isPending, setIsPending] = useState(false);
useEffect(() => {
selectKey(ELTStore[insType].selectedKey);
}, []);
const handleGetData = () => {
const missingFields = validate.call(calculationStore, requiredFields);
if (missingFields && missingFields.length > 0) {
const fieldsNames = getFieldsNames(missingFields);
const msgText = String.prototype.concat(
'Не заполнены поля: ',
fieldsNames.join(', '),
);
setAlert({ message: msgText, type: 'error' });
return;
} else {
setAlert({ message: undefined, type: undefined });
}
setIsPending(true);
const resetPending = () => setIsPending(false);
getData.call(calculationStore, resetPending);
};
const handleSelectRow = () => {
ELTStore[insType].setKey(selectedKey);
onSelectRow.call(calculationStore, insType, selectedKey);
setAlert({ message: 'Выбранные параметры сохранены', type: 'success' });
setTimeout(() => {
setAlert({ message: undefined, type: undefined });
}, 2500);
};
return (
<Controls
title={title}
getData={handleGetData}
selectRow={handleSelectRow}
isLoading={isPending}
>
{alert.message && <Alert {...alert} />}
<InsTable
insType={insType}
selectKey={selectKey}
selectedKey={selectedKey}
{...tableProps}
dataSource={ELTStore[insType].list}
/>
</Controls>
);
};

View File

@ -0,0 +1,39 @@
import { Table as AntTable, TableProps } from 'antd';
import { Box } from 'client/UIKit/grid';
import { toJS } from 'mobx';
import { observer } from 'mobx-react-lite';
import React from 'react';
import styled from 'styled-components';
const TableWrapper = styled(Box)`
.ant-table-row-level-1 .ant-table-selection-column {
visibility: hidden;
}
`;
interface ITableProps {
selectKey: (key: string) => void;
selectedKey: string;
tableConfig: TableProps<any>;
dataSource: any[];
}
export default observer(
({ selectKey, selectedKey, tableConfig, dataSource, ...props }) => {
return (
<TableWrapper my="5px">
<AntTable
{...tableConfig}
rowSelection={Object.assign(tableConfig.rowSelection, {
selectedRowKeys: selectedKey ? [selectedKey] : [],
onSelect: record => {
selectKey(record.key);
},
})}
dataSource={toJS(dataSource)}
{...props}
></AntTable>
</TableWrapper>
);
},
) as React.FC<ITableProps>;

View File

@ -0,0 +1,34 @@
import ReloadOutlined from '@ant-design/icons/lib/icons/ReloadOutlined';
import Button from 'client/Elements/Button';
import { PrimaryText } from 'client/Elements/Text';
import { Flex } from 'client/UIKit/grid';
import { ElementStatus } from 'core/types/statuses';
import styled from 'styled-components';
const TopControls = ({ title, getData, isLoading }) => (
<Flex alignItems="center" justifyContent="space-between" mb="5px">
<PrimaryText>{title}</PrimaryText>
<Button
shape="circle"
status={isLoading ? ElementStatus.Loading : ElementStatus.Default}
action={getData}
icon={<ReloadOutlined />}
/>
</Flex>
);
const BottomControls = ({ selectRow }) => (
<Button text="Применить" action={selectRow}></Button>
);
const ContentWrapper = styled(Flex)`
width: 550px !important;
`;
export default ({ children, ...props }) => (
<ContentWrapper flexDirection="column">
<TopControls {...props} />
{children}
<BottomControls {...props} />
</ContentWrapper>
);

View File

@ -0,0 +1,43 @@
import InsTable from '../InsTable';
import tableConfig from '../lib/config';
export default {
title: 'Components/Calculation/ELT/Kasko',
component: InsTable,
};
const Template = args => <InsTable {...args} />;
const dataSource = [
{
key: '1',
evo_id_elt: 'Alfa',
name: 'Альфа',
sumTitle: 'Премия по договору',
premiumSum: 55555,
message: 'Комментарий альфы',
children: [
{
key: '1',
sumTitle: 'КАСКО',
premiumSum: 1111,
},
{
key: '1',
sumTitle: 'ДГО',
premiumSum: 4444,
},
{
key: '1',
sumTitle: 'НС',
premiumSum: 8888,
},
],
},
];
export const WithData = Template.bind({});
WithData.args = {
tableConfig,
dataSource,
};

View File

@ -0,0 +1,18 @@
import InsContent from '../Components/InsContent';
import tableConfig from '../lib/config';
import getData from '../lib/getData';
import composeRequest from './lib/composeRequest';
import convertEltResult from './lib/convertEltResult';
import onSelectRow from './lib/onSelectRow';
import { requiredFields } from './lib/validation';
const insType = 'kasko';
export default InsContent({
title: 'КАСКО',
insType,
getData: getData(insType, composeRequest, convertEltResult),
onSelectRow,
tableConfig,
requiredFields,
});

View File

@ -0,0 +1,145 @@
import CalculationStore from 'client/stores/CalculationStore';
import { currentDate } from 'core/tools/date';
import composeRequest from './composeRequest';
CalculationStore.options = {
selectRegionRegistration: [
{
evo_name: 'Рязанская область',
value: 'rznregion',
},
],
selectTownRegistration: [
{
evo_name: 'Рязань',
value: 'rzntown',
},
],
selectGPSBrand: [
{
evo_id: 'gps_brand_evo_id',
value: 'gpsbrand',
},
],
selectGPSModel: [
{
evo_id: 'gps_model_evo_id',
value: 'gpsmodel',
},
],
selectBrand: [
{
evo_id: 'AUDI',
value: 'brandid',
},
],
selectModel: [
{
evo_id: 'A5',
value: 'modelid',
},
],
};
CalculationStore.values = {
regionRegistration: 'rznregion',
townRegistration: 'rzntown',
brand: 'brandid',
model: 'modelid',
leaseObjectUsed: false,
leaseObjectYear: 2021,
leaseObjectMotorPower: 5.5,
engineType: undefined,
leasingPeriod: 12,
leaseObjectPrice: 2000,
supplierDiscountRub: 1000,
insFranchise: 5,
GPSBrand: 'gpsbrand',
GPSModel: 'gpsmodel',
insUnlimitDrivers: true,
leaseObjectCategory: 100000002,
maxMass: 1000,
leaseObjectUseFor: 100000001,
INNForCalc: 1010,
};
CalculationStore.tables = {
tableInsurance: {
rows: [{}, {}, { insCost: 10000 }],
},
};
const expected = {
preparams: {
regionName: 'Рязанская область',
cityName: 'Рязань',
brandId: 'AUDI',
modelId: 'A5',
},
ELTParams: {
currency: 'RUR',
isNew: false,
usageStart: currentDate,
vehicleYear: 2021,
modification: {
power: 5.5,
engineType: '5',
engineVolume: 0,
KPPTypeId: '1',
BodyType: '9',
},
duration: 12,
bankId: '245',
cost: 1000,
franchise: '5',
ssType: '1',
STOA: '0',
OfficialDealer: true,
PUUs: [
{
mark: 'gps_brand_evo_id',
model: 'gps_model_evo_id',
},
],
driversCount: 1,
risk: 0,
payType: 0,
vehicle: {
maxAllowedMass: 1000,
mileage: 0,
vehicleUsage: 1,
seatingCapacity: 0,
category: 'C2',
classification: '11635',
},
drivers: [{ age: 18, experience: 0, sex: '0' }],
GO: { limitSumId: '1000000', globalLimitSum: 1000000 },
NS: { LimitSum: 1000000 },
Insurer: {
SubjectType: 1,
SubjectTypeSpecified: true,
},
Owner: {
SubjectType: 1,
SubjectTypeSpecified: true,
},
Lessee: {
SubjectType: 1,
SubjectTypeSpecified: true,
INN: '1010',
},
FullDriversInfo: [
{
surname: 'Иванов',
name: 'Иван',
patronymic: 'Иванович',
sex: '0',
expertienceStart: new Date('2000-01-01'),
},
],
},
};
it('ELT/Kasko/composeRequest', () => {
expect(composeRequest.call(CalculationStore)).toEqual(expected);
});

View File

@ -0,0 +1,200 @@
import { currentDate } from 'core/tools/date';
import { ICalculationStore } from 'core/types/Calculation/Store/index';
import { isNull } from 'lodash';
const mapEngineType = {
100000000: '0',
100000001: '1',
100000003: '2',
100000004: '3',
};
const mapVehicleUsage = {
100000000: 0,
100000001: 1,
100000002: 5,
100000003: 5,
100000004: 2,
100000005: 6,
100000006: 5,
100000007: 4,
100000008: 4,
100000009: 0,
100000010: 0,
100000011: 3,
100000012: 3,
100000013: 9,
};
const mapCategory = {
100000000: 'A',
100000001: 'B',
100000002: 'C2',
100000003: 'D',
100000004: 'E1',
};
const getSpecified = value => !isNull(value);
export default function (this: ICalculationStore) {
const regionName = this.getOption('selectRegionRegistration')?.evo_name;
const cityName = this.getOption('selectTownRegistration')?.evo_name;
const brandId = this.getOption('selectBrand')?.evo_id;
const modelId = this.getOption('selectModel')?.evo_id;
const isNew = !this.getValue('leaseObjectUsed');
const vehicleYear = this.getValue('leaseObjectYear');
const power = this.getValue('leaseObjectMotorPower');
const powerSpecified = getSpecified(power);
let engineType = '5';
const engineTypeValue = this.getValue('engineType');
if (engineTypeValue) {
engineType = mapEngineType[engineTypeValue];
}
const duration = this.getValue('leasingPeriod');
const cost =
this.getValue('leaseObjectPrice') - this.getValue('supplierDiscountRub');
const franchise = this.getValue('insFranchise');
const franchiseSpecified = getSpecified(franchise);
const puuMark = this.getOption('selectGPSBrand')?.evo_id;
const puuModel = this.getOption('selectGPSModel')?.evo_id;
const puuModelSpecified = getSpecified(puuModel);
let age = this.getValue('insAgeDrivers'),
experience = this.getValue('insExpDrivers'),
sex = '0',
driversCount = 1;
if (this.getValue('insUnlimitDrivers')) {
age = 18;
experience = 0;
driversCount = 0;
}
const sexSpecified = getSpecified(sex);
let maxAllowedMass = 0;
if (this.getValue('leaseObjectCategory') === 100000002) {
maxAllowedMass = this.getValue('maxMass');
}
const maxAllowedMassSpecified = getSpecified(maxAllowedMass);
let mileage = 0;
if (this.getValue('leaseObjectUsed')) {
mileage = this.getValue('mileage');
}
const mileageSpecified = getSpecified(mileage);
let vehicleUsage = 0;
const leaseObjectUseForValue = this.getValue('leaseObjectUseFor');
if (leaseObjectUseForValue) {
vehicleUsage = mapVehicleUsage[leaseObjectUseForValue] || 0;
}
const vehicleUsageSpecified = getSpecified(vehicleUsage);
let seatingCapacity = 0;
if (this.getValue('leaseObjectCategory') === 100000003) {
seatingCapacity = this.getValue('countSeats');
}
const seatingCapacitySpecified = getSpecified(seatingCapacity);
const category = mapCategory[this.getValue('leaseObjectCategory')];
const classification = [100000002, 100000003, 100000004].includes(
this.getValue('leaseObjectCategory'),
)
? '11635'
: '0';
const globalLimitSum = this.getTableRowValues('tableInsurance', 2, 'value')
.insCost
? 1000000
: 0;
const globalLimitSumSpecified = getSpecified(globalLimitSum);
const limitSumId = globalLimitSum + '';
const INN = this.getValue('INNForCalc') || '' + '';
return {
preparams: {
regionName,
cityName,
brandId,
modelId,
},
ELTParams: {
currency: 'RUR',
isNew,
usageStart: currentDate,
vehicleYear,
modification: {
power,
powerSpecified,
engineType,
engineVolume: 0,
engineVolumeSpecified: true,
KPPTypeId: 1,
BodyType: 9,
},
duration,
bankId: '245',
cost,
franchise,
franchiseSpecified,
ssType: '1',
STOA: '0',
OfficialDealerSpecified: true,
OfficialDealer: true,
PUUs: puuMark && [
{
mark: puuMark,
model: puuModel,
modelSpecified: puuModelSpecified,
},
],
driversCount,
risk: 0,
payType: '0',
vehicle: {
maxAllowedMass,
maxAllowedMassSpecified,
mileage,
mileageSpecified,
vehicleUsage,
vehicleUsageSpecified,
seatingCapacity,
seatingCapacitySpecified,
category,
classification,
},
drivers: [{ age, experience, sex, sexSpecified }],
GO: { limitSumId, globalLimitSum, globalLimitSumSpecified },
NS: { LimitSum: '1000000' },
Insurer: {
SubjectType: 1,
SubjectTypeSpecified: true,
},
Owner: {
SubjectType: 1,
SubjectTypeSpecified: true,
},
Lessee: {
SubjectType: 1,
SubjectTypeSpecified: true,
INN,
},
// FullDriversInfo: [
// {
// surname,
// name,
// patronymic,
// sex,
// sexSpecified,
// expertienceStart,
// },
// ],
},
};
}

View File

@ -0,0 +1,47 @@
import { get, pick } from 'lodash';
const mapKaskoSums = [
{
sumTitle: 'КАСКО',
sumPath: 'paymentPeriods[0].kaskoSum',
},
{
sumTitle: 'ДГО',
sumPath: 'paymentPeriods[0].goSum',
},
{
sumTitle: 'НС',
sumPath: 'paymentPeriods[0].nsSum',
},
];
export default function (resultCompany, key) {
if (!resultCompany || Object.keys(resultCompany).length === 0) {
return;
}
const dataFromResult = pick(
resultCompany,
['message', 'requestId', 'skCalcId'],
'',
);
const sumsFromResult = Object.fromEntries(
['kaskoSum', 'goSum', 'nsSum', 'premiumSum'].map(x => [
x,
get(resultCompany, 'paymentPeriods[0].' + x, 0),
]),
);
return {
key,
sumType: 'premiumSum',
sumTitle: 'Премия по договору',
...dataFromResult,
...sumsFromResult,
children: mapKaskoSums.map(({ sumPath, ...x }) => ({
key,
...x,
premiumSum: get(resultCompany, sumPath, 0),
})),
};
}

View File

@ -0,0 +1,79 @@
import convertEltResult from './convertEltResult';
export const resultCompany = {
requestId: '1364968',
skCalcId: '66758382',
product: '',
program: '',
productId: '',
programId: '1',
comment: null,
message: 'Комментарий альфы',
error: '',
errorType: null,
premiumSum: 0,
kaskoSum: 0,
doSum: 0,
goSum: 0,
nsSum: 0,
gapSum: 0,
paymentPeriods: [
{
num: 1,
PremiumSum: 55555,
KASKOSum: 1111,
GOSum: 4444,
NSSum: 8888,
},
],
kbmOsago: null,
totalFranchise: 0,
totalFranchiseSpecified: false,
insuranceCompanyFranchise: null,
insuranceCompanyGo: null,
policyNumber: null,
programCode: null,
calcInfo: null,
options: null,
unicusGUID: null,
};
const entityCompany = {
accountid: '0df9ccfb-1407-eb11-af50-00155d088a01',
name: 'Альфа',
evo_id_elt: 'Alfa',
};
it('ELT/Kasko/convertKaskoResultToRow', () => {
expect(convertEltResult(resultCompany, entityCompany, '0')).toEqual({
key: '0',
evo_id_elt: 'Alfa',
name: 'Альфа',
sumType: 'premiumSum',
sumTitle: 'Премия по договору',
PremiumSum: 55555,
KASKOSum: 1111,
GOSum: 4444,
NSSum: 8888,
message: 'Комментарий альфы',
requestId: '1364968',
skCalcId: '66758382',
children: [
{
key: '0',
sumTitle: 'КАСКО',
premiumSum: 1111,
},
{
key: '0',
sumTitle: 'ДГО',
premiumSum: 4444,
},
{
key: '0',
sumTitle: 'НС',
premiumSum: 8888,
},
],
});
});

View File

@ -0,0 +1,35 @@
import { ICalculationStore } from 'core/types/Calculation/Store';
export default function (
this: ICalculationStore,
insType,
selectedKey: string,
) {
const selectedRow = this.stores.ELTStore[insType].list.find(
x => x.key === selectedKey,
);
const { accountid, kaskoSum, goSum, nsSum } = selectedRow;
this.setTableRows(
'tableInsurance',
1,
)([
{
insuranceCompany: {
value: accountid,
},
insCost: { value: kaskoSum },
},
{
insuranceCompany: {
value: accountid,
},
insCost: { value: goSum },
},
{
insuranceCompany: {
value: accountid,
},
insCost: { value: nsSum },
},
]);
}

View File

@ -0,0 +1,13 @@
import { ElementsNames } from 'core/types/Calculation/Store/elements';
export const requiredFields: ElementsNames[] = [
'selectRegionRegistration',
'selectTownRegistration',
'selectBrand',
'selectModel',
'tbxLeaseObjectYear',
'tbxLeaseObjectMotorPower',
'tbxLeasingPeriod',
'tbxLeaseObjectPrice',
'selectLeaseObjectCategory',
];

View File

@ -0,0 +1,18 @@
import InsContent from '../Components/InsContent';
import tableConfig from '../lib/config';
import getData from '../lib/getData';
import composeRequest from './lib/composeRequest';
import convertEltResult from './lib/convertEltResult';
import onSelectRow from './lib/onSelectRow';
import { requiredFields } from './lib/validation';
const insType = 'osago';
export default InsContent({
title: 'ОСАГО',
insType,
getData: getData(insType, composeRequest, convertEltResult),
onSelectRow,
tableConfig,
requiredFields,
});

View File

@ -0,0 +1,149 @@
import { currentDate } from 'core/tools/date';
import { ICalculationStore } from 'core/types/Calculation/Store';
import { isNull } from 'lodash';
const mapCategory = {
100000000: 'A',
100000001: 'B',
100000002: 'C',
100000003: 'D',
100000004: 'ПРОЧИЕ ТС',
};
const mapSubCategoryBuilder = (leaseObjectUseFor, maxMass, countSeats) => ({
100000000: () => '0',
100000001: () => {
if (leaseObjectUseFor === 100000001) {
return '11';
}
return '10';
},
100000002: () => {
if (maxMass <= 16000) {
return '20';
}
return '21';
},
100000003: () => {
if (leaseObjectUseFor === 100000001) {
return '32';
}
if (countSeats <= 20) {
return 30;
}
return '31';
},
100000004: () => '22',
});
const getSpecified = value => !isNull(value);
export default function (this: ICalculationStore) {
const regionName = this.getOption('selectRegionRegistration')?.evo_name;
const cityName = this.getOption('selectTownRegistration')?.evo_name;
const brandId = this.getOption('selectBrand')?.evo_id;
const modelId = this.getOption('selectModel')?.evo_id;
const mark = this.getOption('selectGPSBrand')?.evo_id;
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';
let category = '0';
if (Object.keys(mapCategory).includes(leaseObjectCategory)) {
category = mapCategory[leaseObjectCategory];
}
const leaseObjectUseFor = this.getValue('leaseObjectUseFor');
const maxMass = this.getValue('maxMass');
const countSeats = this.getValue('countSeats');
const mapSubCategory = mapSubCategoryBuilder(
leaseObjectUseFor,
maxMass,
countSeats,
);
const subCategory = mapSubCategory[leaseObjectCategory];
let seatingCapacity = 0;
if (leaseObjectCategory === 100000003) {
seatingCapacity = countSeats;
}
const seatingCapacitySpecified = getSpecified(seatingCapacity);
let maxAllowedMass = 0;
if (leaseObjectCategory === 100000002) {
maxAllowedMass = maxMass;
}
const maxAllowedMassSpecified = getSpecified(maxAllowedMass);
const useWithTrailer = this.getValue('withTrailer');
const useWithTrailerSpecified = true;
const address = {
resident: 1,
country: 'Российская Федерация',
region: 'Москва',
district: '0',
city: 'Москва',
cityKladr: '7700000000000',
street: 'ул. Котляковская',
streetKladr: '0',
house: '8',
korpus: '0',
flat: '337',
};
const owner = {
JuridicalName: 'ООО "ЛК "ЭВОЛЮЦИЯ"',
inn: '9724016636',
kpp: '772401001',
ogrn: '1207700245037',
registrationAddress: address,
factAddress: address,
phone: '8 (800) 333-75-75',
email: 'client@evoleasing.ru',
};
return {
preparams: {
regionName,
cityName,
brandId,
modelId,
},
ELTParams: {
tsToRegistrationPlace: 0,
contractBeginDate: currentDate,
duration: 12,
carInfo: {
mark,
model,
vehicleYear,
vehiclePower,
tsType: { category, subCategory },
vehicle: {
regNumber: '0',
bodyNumber: '0',
chassisNumber: '0',
VIN: '0',
seatingCapacity,
seatingCapacitySpecified,
maxAllowedMass,
maxAllowedMassSpecified,
},
useWithTrailer,
useWithTrailerSpecified,
},
owner,
FullDriversInfo: [
{
kbm: '3',
},
],
},
};
}

View File

@ -0,0 +1,20 @@
import { pick } from 'lodash';
export default function (resultCompany, key) {
if (!resultCompany || Object.keys(resultCompany).length === 0) {
return;
}
const dataFromResult = pick(
resultCompany,
['numCalc', 'premiumSum', 'message'],
'',
);
return {
key,
sumType: 'premiumSum',
sumTitle: 'Премия по договору',
...dataFromResult,
};
}

View File

@ -0,0 +1,21 @@
import { ICalculationStore } from 'core/types/Calculation/Store';
export default function (
this: ICalculationStore,
insType,
selectedKey: string,
) {
const selectedRow = this.stores.ELTStore[insType].list.find(
x => x.key === selectedKey,
);
const { accountid, premiumSum } = selectedRow;
this.setTableRow(
'tableInsurance',
0,
)({
insuranceCompany: {
value: accountid,
},
insCost: { value: premiumSum },
});
}

View File

@ -0,0 +1,13 @@
import { ElementsNames } from 'core/types/Calculation/Store/elements';
export const requiredFields: ElementsNames[] = [
'selectRegionRegistration',
'selectTownRegistration',
'selectBrand',
'selectModel',
'tbxLeaseObjectYear',
'tbxLeaseObjectMotorPower',
'tbxLeasingPeriod',
'tbxLeaseObjectPrice',
'selectLeaseObjectCategory',
];

View File

@ -0,0 +1,20 @@
import { Flex } from 'client/UIKit/grid';
import mq from 'client/UIKit/mq';
import styled from 'styled-components';
import Kasko from './Kasko';
import Osago from './Osago';
const ContentDivider = styled.div`
margin: 16px 0;
${mq.laptopHD`
margin: 0 16px;
`}
`;
export default () => (
<Flex flexDirection={['column', 'column', 'column', 'row']}>
<Osago />
<ContentDivider />
<Kasko />
</Flex>
);

View File

@ -0,0 +1,21 @@
export type KaskoDataNames = 'name' | 'sumTitle' | 'premiumSum';
const columns: { title: string; dataIndex: KaskoDataNames }[] = [
{
title: 'Страховая компания',
dataIndex: 'name',
},
{
title: '',
dataIndex: 'sumTitle',
},
{
title: 'Сумма',
dataIndex: 'premiumSum',
//@ts-ignore
sorter: (a, b) => a.premiumSum - b.premiumSum,
sortDirections: ['descend', 'ascend'],
},
];
export default columns;

View File

@ -0,0 +1,18 @@
import { TableProps } from 'antd';
import columns from './columns';
export default {
columns,
rowSelection: {
hideSelectAll: true,
type: 'radio',
},
expandable: {
// rowExpandable: record => record.message || record.children,
// expandedRowRender: record => record.message,
// expandRowByClick: true,
// expandIconColumnIndex: -1,
},
pagination: false,
size: 'small',
} as TableProps<any>;

View File

@ -0,0 +1,40 @@
import ELTService from 'core/services/ELTService';
import { ICalculationStore } from 'core/types/Calculation/Store';
import { IAccount } from 'core/types/Entities/crmEntities';
export default (insType: string, composeRequest, convertEltResult) =>
function (this: ICalculationStore, callback: () => any) {
const { ELTStore } = this.stores;
const request = composeRequest.call(this);
const requests = ELTStore[insType].list.map(
(company: IAccount, i: number) =>
new Promise<void>((resolve, reject) => {
ELTService[insType]
.getCalculation({
companyIds: [company.evo_id_elt],
...request,
})
.then(res => {
if (!company.evo_id_elt || !res[company.evo_id_elt]) {
return;
}
const converted = convertEltResult(
res[company.evo_id_elt],
company.accountid,
);
ELTStore.setCompanyRes(
insType,
i,
Object.assign(company, converted),
);
resolve();
})
.catch(err => {
reject(err);
});
}),
);
Promise.allSettled(requests).then(() => callback());
};

View File

@ -0,0 +1,19 @@
import { elementsTitles } from 'client/Containers/Calculation/lib/elements/titles';
import { elementsValues } from 'client/Containers/Calculation/lib/elements/values';
import { ICalculationStore } from 'core/types/Calculation/Store';
import { ElementsNames } from 'core/types/Calculation/Store/elements';
export function validate(this: ICalculationStore, requiredValues) {
const missingValues = requiredValues.filter(x => {
const valueName = elementsValues[x] || '';
return (
this.values[valueName] === undefined || this.values[valueName] === null
);
});
return missingValues;
}
export function getFieldsNames(elementsNames: ElementsNames[]): string[] {
return elementsNames.map(x => elementsTitles[x] || '');
}

View File

@ -0,0 +1,44 @@
import { Modal } from 'antd';
import { Outlined as SpinnerOutlined } from 'client/Components/Spinner';
import Button from 'client/Elements/Button';
import { Box } from 'client/UIKit/grid';
import { lazy, Suspense, useState } from 'react';
const Content = lazy(() => import('./Content'));
const ELT = ({ title }) => {
const [isOpenModal, setIsOpenModal] = useState(false);
function closeModal() {
setIsOpenModal(false);
}
return (
<>
<Box mb="24px">
<Button
style={{ width: '100%' }}
text={title}
action={() => {
setIsOpenModal(!isOpenModal);
}}
/>
</Box>
{isOpenModal && (
<Modal
title={title}
visible={isOpenModal}
onOk={closeModal}
onCancel={closeModal}
footer={null}
width="max-content"
centered
>
<Suspense fallback={<SpinnerOutlined />}>
<Content />
</Suspense>
</Modal>
)}
</>
);
};
export default ELT;

View File

@ -1,10 +1,21 @@
import LoadingOutlined from '@ant-design/icons/lib/icons/LoadingOutlined';
import { Spin } from 'antd'; import { Spin } from 'antd';
import { Box, Flex } from 'client/UIKit/grid'; import { Flex } from 'client/UIKit/grid';
export default () => ( const Wrapper = props => (
<Box height="100%" py="10px"> <Flex height="100%" py="10px" justifyContent="center" alignItems="center">
<Flex justifyContent="center" alignItems="center"> {props.children}
<Spin /> </Flex>
</Flex>
</Box>
); );
const Spinner = props => (
<Wrapper>
<Spin {...props} />
</Wrapper>
);
export default Spinner;
const loadingOutlined = <LoadingOutlined style={{ fontSize: 24 }} spin />;
export const Outlined = () => <Spinner indicator={loadingOutlined} />;

View File

@ -11,10 +11,4 @@ const Results = props => (
</Background> </Background>
); );
const styles = {
divider: {
margin: '12px 0',
},
};
export default Results; export default Results;

View File

@ -307,7 +307,7 @@ const sections: ISection[] = [
style: { columnsNumber: 1 }, style: { columnsNumber: 1 },
blocks: [ blocks: [
{ {
elements: ['tableInsurance'], elements: ['componentElt', 'tableInsurance'],
}, },
], ],
}, },

View File

@ -49,6 +49,9 @@ export function buildElement(elementName) {
...elementProps, ...elementProps,
}); });
} }
case ElementType.Custom: {
return () => <Component {...elementProps} />;
}
default: { default: {
return withValue(Component)({ return withValue(Component)({
name: elementName, name: elementName,

View File

@ -1,3 +1,4 @@
import ELT from 'client/Components/Calculation/ELT';
import Button from 'client/Elements/Button'; import Button from 'client/Elements/Button';
import Checkbox from 'client/Elements/Checkbox'; import Checkbox from 'client/Elements/Checkbox';
import Download from 'client/Elements/Download'; import Download from 'client/Elements/Download';
@ -160,6 +161,7 @@ const elementsComponents: TElements<Component> = {
tbxMileage: InputNumber, tbxMileage: InputNumber,
radioCalcType: Radio, radioCalcType: Radio,
tbxTotalPayments: InputNumber, tbxTotalPayments: InputNumber,
componentElt: ELT,
}; };
const tablesComponents: StoreTables<Component> = { const tablesComponents: StoreTables<Component> = {

View File

@ -336,6 +336,9 @@ const elementsProps: TElements<ElementProps> = {
step: 1000, step: 1000,
precision: 2, precision: 2,
}, },
componentElt: {
title: 'Расчет страховки в ЭЛТ',
},
}; };
const resultElementsProps: TElements<ElementProps> = [ const resultElementsProps: TElements<ElementProps> = [

View File

@ -1,7 +1,7 @@
import { TElements } from 'core/types/Calculation/Store/elements'; import { TElements } from 'core/types/Calculation/Store/elements';
import { StoreTables } from 'core/types/Calculation/Store/tables'; import { StoreTables } from 'core/types/Calculation/Store/tables';
const elementsTitles: TElements<string> = { export const elementsTitles: TElements<string> = {
selectLead: 'Интерес', selectLead: 'Интерес',
selectOpportunity: 'Лизинговая сделка', selectOpportunity: 'Лизинговая сделка',
selectQuote: 'Предложение', selectQuote: 'Предложение',

View File

@ -1,5 +1,5 @@
import { ElementType, TElements } from 'core/types/Calculation/Store/elements';
import { StoreTables } from 'core/types/Calculation/Store/tables'; import { StoreTables } from 'core/types/Calculation/Store/tables';
import { TElements, ElementType } from 'core/types/Calculation/Store/elements';
const elementsTypes: TElements<ElementType> = { const elementsTypes: TElements<ElementType> = {
labelLeaseObjectRisk: ElementType.Computed, labelLeaseObjectRisk: ElementType.Computed,
@ -11,6 +11,7 @@ const elementsTypes: TElements<ElementType> = {
btnCalculate: ElementType.Action, btnCalculate: ElementType.Action,
labelIrrInfo: ElementType.Computed, labelIrrInfo: ElementType.Computed,
linkDownloadKp: ElementType.Link, linkDownloadKp: ElementType.Link,
componentElt: ElementType.Custom,
}; };
const tablesTypes: StoreTables<ElementType> = { const tablesTypes: StoreTables<ElementType> = {

View File

@ -37,14 +37,16 @@ export default () =>
{ {
entities: { systemuser }, entities: { systemuser },
}, },
{ entities: insuranceCompanies }, {
entities: { insuranceCompany },
},
]) => { ]) => {
CalculationStore.applyOptions(ownerOptions); CalculationStore.applyOptions(ownerOptions);
CalculationStore.applyOptions(initialOptions); CalculationStore.applyOptions(initialOptions);
CalculationStore.applyStaticData(staticEntities); CalculationStore.applyStaticData(staticEntities);
CalculationStore.applyStaticData({ systemuser: [systemuser] }); CalculationStore.applyStaticData({ systemuser: [systemuser] });
CalculationStore.setTableColumns('tableInsurance')({ CalculationStore.setTableColumns('tableInsurance')({
options: { ...insuranceCompanies }, options: { insuranceCompany },
}); });
const supplierCurrency = CalculationStore.options.selectSupplierCurrency?.find( const supplierCurrency = CalculationStore.options.selectSupplierCurrency?.find(

View File

@ -1,5 +1,5 @@
import { IQueryToCRMGQL } from 'core/types/Calculation/Requests';
import { gql } from '@apollo/client'; import { gql } from '@apollo/client';
import { IQueryToCRMGQL } from 'core/types/Calculation/Requests';
const query = gql` const query = gql`
query($evo_account_type: [Int!], $statecode: Int) { query($evo_account_type: [Int!], $statecode: Int) {
@ -10,6 +10,7 @@ const query = gql`
accountid accountid
name name
evo_type_ins_policy evo_type_ins_policy
evo_id_elt
} }
} }
`; `;

View File

@ -66,6 +66,7 @@ const query = gql`
evo_client_riskid evo_client_riskid
} }
selectBrand: evo_brands(statecode: $statecode) { selectBrand: evo_brands(statecode: $statecode) {
evo_id
evo_name evo_name
evo_brandid evo_brandid
evo_importer_reward_perc evo_importer_reward_perc

View File

@ -1,4 +1,5 @@
import { Divider as AntDivider, Tabs } from 'antd'; import { Tabs } from 'antd';
import Divider from 'client/Elements/Divider';
import { SecondaryColoredText } from 'client/Elements/Text'; import { SecondaryColoredText } from 'client/Elements/Text';
import colors from 'client/UIKit/colors'; import colors from 'client/UIKit/colors';
import { Box, Flex } from 'client/UIKit/grid'; import { Box, Flex } from 'client/UIKit/grid';
@ -37,13 +38,11 @@ const renderBlocks = ({ blocks }) => {
return null; return null;
} }
return blocks.map((block, ib) => { return blocks.map((block, ib) => {
const { elements, title: blockTitle } = block; const { elements, title } = block;
return ( return (
<Fragment key={ib}> <Fragment key={ib}>
<Flex flexDirection="column" flexWrap="nowrap"> <Flex flexDirection="column" flexWrap="nowrap">
{blockTitle && ( {title && <SecondaryColoredText>{title}</SecondaryColoredText>}
<SecondaryColoredText>{blockTitle}</SecondaryColoredText>
)}
{renderElements({ elements })} {renderElements({ elements })}
</Flex> </Flex>
</Fragment> </Fragment>
@ -51,18 +50,11 @@ const renderBlocks = ({ blocks }) => {
}); });
}; };
const BlocksTitle = ({ text }) => const BlocksTitle = styled(Divider)`
text ? ( margin: 16px 0;
<AntDivider color: ${colors.primary} !important;
style={{ font-size: 0.95rem;
margin: '16px 0', `;
color: colors.primary,
fontSize: '0.95rem',
}}
>
{text}
</AntDivider>
) : null;
const BlocksGrid = styled(Box)` const BlocksGrid = styled(Box)`
display: grid; display: grid;
@ -80,11 +72,11 @@ export const renderGroups = ({ groups }) => {
return null; return null;
} }
return groups.map((group, ig) => { return groups.map((group, ig) => {
const { title: blocksTitle, blocks, style } = group; const { title, blocks, style } = group;
return ( return (
<Box key={ig} my="5px"> <Box key={ig} my="5px">
<BlocksTitle text={blocksTitle} /> {title && <BlocksTitle>{title}</BlocksTitle>}
<BlocksGrid {...style}>{renderBlocks({ blocks })}</BlocksGrid> <BlocksGrid {...style}>{renderBlocks({ blocks })}</BlocksGrid>
</Box> </Box>
); );
@ -95,9 +87,9 @@ export const renderSections = ({ sectionsList }) => {
return ( return (
<Tabs type="line"> <Tabs type="line">
{sectionsList.map((section, is) => { {sectionsList.map((section, is) => {
const { title: tabTitle, groups } = section; const { title, groups } = section;
return ( return (
<Tabs.TabPane tab={tabTitle} key={is} forceRender> <Tabs.TabPane tab={title} key={is} forceRender>
{renderGroups({ groups })} {renderGroups({ groups })}
</Tabs.TabPane> </Tabs.TabPane>
); );

View File

@ -0,0 +1,5 @@
import { Alert as AntAlert } from 'antd';
const Alert = props => <AntAlert {...props} />;
export default Alert;

View File

@ -0,0 +1,3 @@
import { Divider } from 'antd';
export default Divider;

View File

@ -14,3 +14,8 @@ export const SecondaryText = styled(PrimaryText)`
export const SecondaryColoredText = styled(SecondaryText)` export const SecondaryColoredText = styled(SecondaryText)`
color: ${colors.secondary}; color: ${colors.secondary};
`; `;
export const ErrorText = styled(PrimaryText)`
font-size: 0.9rem;
color: red;
`;

View File

@ -1,7 +1,8 @@
import { useStores } from '../useStores'; import { useStores } from '../useStores';
export const useUrl = ({ urlName }) => { export const useUrl = ({ urlName }) => {
const { calculationUrls } = useStores(); const { calculationStore } = useStores();
const { calculationUrls } = calculationStore.stores;
const url = calculationUrls.urls[urlName]; const url = calculationUrls.urls[urlName];
return { url }; return { url };
}; };

View File

@ -40,7 +40,8 @@ export const useTableValue = ({
propName, propName,
columnCallback, columnCallback,
}) => { }) => {
const { calculationStore, calculationProcess } = useStores(); const { calculationStore } = useStores();
const { calculationProcess } = calculationStore.stores;
const [currentValue, setCurrentValue] = useState(undefined); const [currentValue, setCurrentValue] = useState(undefined);
//get row value from store //get row value from store

View File

@ -29,6 +29,10 @@ const tablesActions = {
return values; return values;
}, },
getTableOptions(tableName, propName) {
return this.tables[tableName].options[propName];
},
replaceTableRows(tableName) { replaceTableRows(tableName) {
return rows => { return rows => {
this.tables[tableName].rows.replace(rows); this.tables[tableName].rows.replace(rows);

View File

@ -3,7 +3,7 @@ import { currentDate } from 'core/tools/date';
import { PaymentRow, PreparedValues } from 'core/types/Calculation/Prepare'; import { PaymentRow, PreparedValues } from 'core/types/Calculation/Prepare';
import { IPreparedData } from 'core/types/Calculation/Requests'; import { IPreparedData } from 'core/types/Calculation/Requests';
import { ICalculationStore } from 'core/types/Calculation/Store'; import { ICalculationStore } from 'core/types/Calculation/Store';
import NIL from 'uuid/dist/esm-browser/nil'; import NIL from 'uuid/dist/nil';
import { convertPrice } from '../../lib/tools'; import { convertPrice } from '../../lib/tools';
export default ({ export default ({

View File

@ -5,13 +5,14 @@ import UserStore from 'client/stores/UserStore';
import { CRM_PROXY_URL } from 'core/constants/urls'; import { CRM_PROXY_URL } from 'core/constants/urls';
import CrmService from 'core/services/CrmService'; import CrmService from 'core/services/CrmService';
import { toJS } from 'mobx'; import { toJS } from 'mobx';
import CalculationStore, { calculationUrls } from '../..'; import CalculationStore from '../..';
import customValues from '../lib/customValues'; import customValues from '../lib/customValues';
import { quoteFields } from '../lib/queries'; import { quoteFields } from '../lib/queries';
import calculate from './calculate'; import calculate from './calculate';
export default async () => { export default async () => {
const { values, tables } = CalculationStore; const { values, tables } = CalculationStore;
const { calculationUrls } = CalculationStore.stores;
const calculationRes = await calculate(); const calculationRes = await calculate();
if (!calculationRes) { if (!calculationRes) {

View File

@ -2,7 +2,6 @@
import { message } from 'antd'; import { message } from 'antd';
import { elementsValues } from 'client/Containers/Calculation/lib/elements/values'; import { elementsValues } from 'client/Containers/Calculation/lib/elements/values';
import { openNotification } from 'client/Elements/Notification'; import { openNotification } from 'client/Elements/Notification';
import { calculationProcess } from 'client/stores/CalculationStore';
import initialValues from 'client/stores/CalculationStore/config/initialValues'; import initialValues from 'client/stores/CalculationStore/config/initialValues';
import CrmService from 'core/services/CrmService'; import CrmService from 'core/services/CrmService';
import { currentISODate } from 'core/tools/date'; import { currentISODate } from 'core/tools/date';
@ -12,7 +11,7 @@ import { TElements } from 'core/types/Calculation/Store/elements';
import { Process } from 'core/types/Calculation/Store/process'; import { Process } from 'core/types/Calculation/Store/process';
import { IEvoGraph } from 'core/types/Entities/crmEntities'; import { IEvoGraph } from 'core/types/Entities/crmEntities';
import { ElementStatus } from 'core/types/statuses'; import { ElementStatus } from 'core/types/statuses';
import { NIL } from 'uuid'; import NIL from 'uuid/dist/nil';
import mapKPtoValues from './mapKpToValues'; import mapKPtoValues from './mapKpToValues';
import optionsQuery from './optionsQuery'; import optionsQuery from './optionsQuery';
import quoteQuery from './quoteQuery'; import quoteQuery from './quoteQuery';
@ -63,6 +62,8 @@ const loadKpReaction: IReactionEffect = calculationStore => ({
calculationStore.setStatus('btnCalculate', ElementStatus.Disabled); calculationStore.setStatus('btnCalculate', ElementStatus.Disabled);
calculationStore.setStatus('btnCreateKP', ElementStatus.Disabled); calculationStore.setStatus('btnCreateKP', ElementStatus.Disabled);
const { calculationProcess } = calculationStore.stores;
CrmService.crmgqlquery({ CrmService.crmgqlquery({
query: quoteQuery, query: quoteQuery,
variables: { variables: {

View File

@ -812,6 +812,7 @@ export default [
statecode: $statecode statecode: $statecode
evo_brandid: $evo_brandid evo_brandid: $evo_brandid
) { ) {
evo_id
evo_name evo_name
evo_modelid evo_modelid
evo_leasingobject_risk evo_leasingobject_risk

View File

@ -0,0 +1,49 @@
import { IWhenEffect } from 'core/types/Calculation/Store/effect'; // @ts-nocheck
import { pick } from 'lodash';
const mapInsType = {
kasko: 100000000,
osago: 100000001,
};
const whenEffects: IWhenEffect[] = [
calculationStore => ({
predicate: () => {
const insuranceCompanies = calculationStore.getTableOptions(
'tableInsurance',
'insuranceCompany',
);
return insuranceCompanies !== undefined && insuranceCompanies.length > 0;
},
effect: () => {
const insuranceCompanies = calculationStore.getTableOptions(
'tableInsurance',
'insuranceCompany',
);
if (insuranceCompanies === undefined) {
return;
}
const { ELTStore } = calculationStore.stores;
insuranceCompanies.forEach(company => {
if (company.evo_id_elt) {
const companyData = pick(
company,
['evo_id_elt', 'name', 'accountid'],
'',
);
Object.keys(mapInsType).forEach(insType => {
if (
company &&
company.evo_type_ins_policy &&
company.evo_type_ins_policy.includes(mapInsType[insType])
) {
ELTStore[insType].list.push(companyData);
}
});
}
});
},
}),
];
export default whenEffects;

View File

@ -1,55 +1,20 @@
import { ElementParam, ICalculationStore } from 'core/types/Calculation/Store'; import { ICalculationStore } from 'core/types/Calculation/Store';
import { ElementsNames } from 'core/types/Calculation/Store/elements';
import { LinksNames } from 'core/types/Calculation/Store/links';
import { Process } from 'core/types/Calculation/Store/process';
import { TableNames } from 'core/types/Calculation/Store/tables';
import { ElementStatus } from 'core/types/statuses';
import { isEqual } from 'lodash'; import { isEqual } from 'lodash';
import { autorun, makeAutoObservable, reaction } from 'mobx'; import { autorun, makeAutoObservable, reaction, when } from 'mobx';
import staticData from './Data/static'; import staticData from './Data/static';
import tables from './Data/tables'; import tables from './Data/tables';
import values from './Data/values'; import values from './Data/values';
import autorunEffects from './Effects/autorun'; import autorunEffects from './Effects/autorun';
import computedEffects from './Effects/computed'; import computedEffects from './Effects/computed';
import reactionEffects from './Effects/reactions'; import reactionEffects from './Effects/reactions';
import whenEffects from './Effects/when';
import subStores from './subStores';
export const calculationProcess = makeAutoObservable({ const { calculationProcess } = subStores;
process: Process.Default,
setProcess(process) {
this.process = process;
},
bypass: {
status: undefined,
},
setBypass({
param,
target,
value,
}: {
param: ElementParam;
target: (ElementsNames | TableNames)[];
value: ElementStatus;
}) {
this.bypass[param] = { target, value };
},
clearBypass(param: ElementParam) {
this.bypass[param] = undefined;
},
});
export const calculationUrls = makeAutoObservable({
urls: {},
setUrl({ name, url }: { name: LinksNames; url: string }) {
this.urls[name] = url;
},
});
const CalculationStore: ICalculationStore = makeAutoObservable( const CalculationStore: ICalculationStore = makeAutoObservable(
Object.assign({}, staticData, values, tables, computedEffects, { Object.assign({}, staticData, values, tables, computedEffects, {
stores: { stores: subStores,
calculationProcess,
},
}), }),
); );
@ -68,4 +33,9 @@ reactionEffects.map(reactionEffectBuilder => {
}); });
}); });
whenEffects.map(whenEffectBuilder => {
const whenEffect = whenEffectBuilder(CalculationStore);
return when(whenEffect.predicate, whenEffect.effect);
});
export default CalculationStore; export default CalculationStore;

View File

@ -0,0 +1,35 @@
import { ElementParam } from 'core/types/Calculation/Store';
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 { makeAutoObservable } from 'mobx';
const calculationProcess = makeAutoObservable({
process: Process.Default,
setProcess(process) {
this.process = process;
},
bypass: {
status: undefined,
},
setBypass({
param,
target,
value,
}: {
param: ElementParam;
target: (ElementsNames | TableNames)[];
value: ElementStatus;
}) {
this.bypass[param] = { target, value };
},
clearBypass(param: ElementParam) {
this.bypass[param] = undefined;
},
});
export default calculationProcess;
export type TCalculationProcess = typeof calculationProcess;

View File

@ -0,0 +1,13 @@
import { LinksNames } from 'core/types/Calculation/Store/links';
import { makeAutoObservable } from 'mobx';
const calculationUrls = makeAutoObservable({
urls: {},
setUrl({ name, url }: { name: LinksNames; url: string }) {
this.urls[name] = url;
},
});
export default calculationUrls;
export type TCalculationUrls = typeof calculationUrls;

View File

@ -0,0 +1,32 @@
// @ts-nocheck
import { makeAutoObservable } from 'mobx';
const ELTStore = makeAutoObservable(
Object.assign(
{},
...['osago', 'kasko'].map(x => ({
[x]: {
list: [],
selectedKey: '',
setKey(key) {
this.selectedKey = key;
},
getSelectedCompany() {
const selectedItem = this.list.find(
x => x.evo_id_elt === this.selectedKey,
);
return selectedItem;
},
},
})),
{
setCompanyRes(insType, index, res) {
this[insType].list[index] = res;
},
},
),
);
export type TELTStore = typeof ELTStore;
export default ELTStore;

View File

@ -0,0 +1,9 @@
import calculationProcess from './calculationProcess';
import calculationUrls from './calculationUrls';
import ELTStore from './eltStore';
export default {
calculationProcess,
calculationUrls,
ELTStore,
};

View File

@ -1,14 +1,9 @@
import CalculationStore, { import CalculationStore from './CalculationStore';
calculationProcess,
calculationUrls,
} from './CalculationStore';
import UserStore from './UserStore'; import UserStore from './UserStore';
class RootStore { class RootStore {
constructor() { constructor() {
this.calculationStore = CalculationStore; this.calculationStore = CalculationStore;
this.calculationProcess = calculationProcess;
this.calculationUrls = calculationUrls;
this.userStore = UserStore; this.userStore = UserStore;
} }
} }

View File

@ -1,3 +1,4 @@
export const CRM_PROXY_URL = '/crmgraphql'; export const CRM_PROXY_URL = '/crmgraphql';
export const CORE_PROXY_URL = '/core'; export const CORE_PROXY_URL = '/core';
export const AUTH_PROXY_URL = '/auth-srv'; export const AUTH_PROXY_URL = '/auth-srv';
export const ELT_PROXY_URL = '/elt';

View File

@ -0,0 +1,23 @@
import axios from 'axios';
import { ELT_PROXY_URL } from 'core/constants/urls';
export default class {
static getCalculation = payload =>
new Promise((resolve, reject) => {
axios
.post(
String.prototype.concat(
ELT_PROXY_URL,
'/insurance',
'/calculateKasko',
),
payload,
)
.then(res => {
resolve(res.data);
})
.catch(err => {
reject(err);
});
});
}

View File

@ -0,0 +1,24 @@
import axios from 'axios';
import { ELT_PROXY_URL } from 'core/constants/urls';
export default class {
static getCalculation = payload =>
new Promise((resolve, reject) => {
axios
.post(
String.prototype.concat(
ELT_PROXY_URL,
'/insurance',
'/calculateOsago',
),
payload,
)
.then(res => {
resolve(res.data);
})
.catch(err => {
reject(err);
throw err.response.data;
});
});
}

View File

@ -0,0 +1,4 @@
import kasko from './Kasko';
import osago from './Osago';
export default { kasko, osago };

View File

@ -1,4 +1,4 @@
import { calculationProcess } from 'client/stores/CalculationStore'; import { TCalculationProcess } from 'client/stores/CalculationStore/subStores/calculationProcess';
import { IReactionOptions, IReactionPublic, Lambda } from 'mobx'; import { IReactionOptions, IReactionPublic, Lambda } from 'mobx';
import { ICalculationStore } from './'; import { ICalculationStore } from './';
@ -8,8 +8,6 @@ export type TAction = {
[actionName in ActionsNames]?: () => void; [actionName in ActionsNames]?: () => void;
}; };
export type TCalculationProcess = typeof calculationProcess;
export interface IAutorunEffect { export interface IAutorunEffect {
(CalculationStore: ICalculationStore): () => void; (CalculationStore: ICalculationStore): () => void;
} }

View File

@ -157,14 +157,23 @@ export type ResultElementsNames =
| 'labelResultDopMPLLeasing' | 'labelResultDopMPLLeasing'
| 'labelResultBonusDopProd'; | 'labelResultBonusDopProd';
export type CustomComponents = 'componentElt';
export type AllElements =
| ElementsNames
| ResultElementsNames
| LinkElementsNames
| CustomComponents;
export enum ElementType { export enum ElementType {
Default, Default,
Computed, Computed,
Table, Table,
Action, Action,
Link, Link,
Custom,
} }
export type TElements<T> = { export type TElements<T> = {
[elementName in ElementsNames | ResultElementsNames | LinkElementsNames]?: T; [elementName in AllElements]?: T;
}; };

View File

@ -1,3 +1,6 @@
import { TCalculationProcess } from 'client/stores/CalculationStore/subStores/calculationProcess';
import { TCalculationUrls } from 'client/stores/CalculationStore/subStores/calculationUrls';
import { TELTStore } from 'client/stores/CalculationStore/subStores/eltStore';
import { TCRMEntity } from '../../Entities/crmEntities'; import { TCRMEntity } from '../../Entities/crmEntities';
import { CRMEntityNames } from '../../Entities/crmEntityNames'; import { CRMEntityNames } from '../../Entities/crmEntityNames';
import { ElementStatus } from '../../statuses'; import { ElementStatus } from '../../statuses';
@ -11,6 +14,7 @@ import {
StoreTables, StoreTables,
TableNames, TableNames,
TableProps, TableProps,
TableValuesNames,
TCellCallback, TCellCallback,
} from './tables'; } from './tables';
import { ResultValuesNames, TValue, TValues, ValuesNames } from './values'; import { ResultValuesNames, TValue, TValues, ValuesNames } from './values';
@ -78,7 +82,12 @@ interface ICalculationTables {
tableName: TableNames, tableName: TableNames,
rowIndex: number, rowIndex: number,
paramName: ElementParam, paramName: ElementParam,
) => { values: TableProps<any> }; ) => TableProps<any>;
getTableOptions: (
tableName: TableNames,
propName: TableValuesNames,
) => (IBaseOption & TCRMEntity)[] | undefined;
replaceTableRows: ( replaceTableRows: (
tableName: TableNames, tableName: TableNames,
@ -108,4 +117,14 @@ interface ICalculationTables {
}) => void; }) => void;
} }
export type ICalculationStore = ICalculationValues & ICalculationTables; interface ICalculationStores {
stores: {
calculationProcess: TCalculationProcess;
calculationUrls: TCalculationUrls;
ELTStore: TELTStore;
};
}
export type ICalculationStore = ICalculationValues &
ICalculationTables &
ICalculationStores;

View File

@ -1,8 +1,9 @@
import { TCalculationProcess } from 'client/stores/CalculationStore/subStores/calculationProcess';
import { Component } from 'core/types/Calculation/components';
import { ElementStatus } from '../../statuses'; import { ElementStatus } from '../../statuses';
import { ElementProps } from '../components'; import { ElementProps } from '../components';
import { ICalculationStore } from './'; import { ICalculationStore } from './';
import { TCRMEntity } from './../../Entities/crmEntities'; import { TCRMEntity } from './../../Entities/crmEntities';
import { TCalculationProcess } from './effect';
import { TElementFilter } from './filters'; import { TElementFilter } from './filters';
import { IBaseOption } from './options'; import { IBaseOption } from './options';
@ -45,7 +46,7 @@ export type TableColumnCallbacks = TableProps<TCellCallback>;
export type TableColumn = { export type TableColumn = {
name: TableValuesNames; name: TableValuesNames;
title: string; title: string;
Component: () => JSX.Element; Component: Component;
props?: ElementProps; props?: ElementProps;
}; };

View File

@ -1,21 +1,13 @@
import { import React from 'react';
ElementsNames, import { AllElements } from './Store/elements';
LinkElementsNames,
ResultElementsNames,
} from './Store/elements';
import { TableNames } from './Store/tables'; import { TableNames } from './Store/tables';
export type ElementProps = { [key: string]: any }; export type ElementProps = { [key: string]: any };
export type Component = () => JSX.Element; export type Component = React.FC<any>;
interface IBlock { interface IBlock {
title?: string; title?: string;
elements: ( elements: (AllElements | TableNames)[];
| ElementsNames
| ResultElementsNames
| TableNames
| LinkElementsNames
)[];
[key: string]: any; [key: string]: any;
} }

View File

@ -16,6 +16,7 @@ export interface IAccount {
customerid?: string; customerid?: string;
evo_kpp?: string; evo_kpp?: string;
evo_address_legalidData?: IEvoAddress; evo_address_legalidData?: IEvoAddress;
evo_id_elt?: string;
} }
export interface IEvoAddress { export interface IEvoAddress {