merge branch dev/eslint-config

This commit is contained in:
vchikalkin 2023-02-06 12:19:39 +03:00
parent 96c4a095b1
commit b15de1ffe2
210 changed files with 2788 additions and 2208 deletions

View File

@ -8,3 +8,6 @@ coverage
.eslintrc.js .eslintrc.js
**/*.config.js **/*.config.js
**/scripts **/scripts
packages/eslint-config-custom/*
**/package.json
turbo.json

View File

@ -1,10 +1,13 @@
module.exports = { module.exports = {
root: true, root: true,
// This tells ESLint to load the config from the package `eslint-config-custom` // This tells ESLint to load the config from the package `eslint-config-custom`
extends: ['custom'], extends: ['custom', 'custom/rules'],
settings: { settings: {
next: { next: {
rootDir: ['apps/*/', 'packages/*/'], rootDir: ['packages/web/'],
},
react: {
version: 'detect',
}, },
}, },
}; };

16
.vscode/settings.json vendored
View File

@ -13,10 +13,18 @@
"editor.defaultFormatter": "esbenp.prettier-vscode", "editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true, "editor.formatOnSave": true,
"editor.codeActionsOnSave": { "editor.codeActionsOnSave": {
"source.organizeImports": true, "source.fixAll": true,
"source.fixAll.eslint": true, "source.fixAll.eslint": true
"source.fixAll.format": true
}, },
"workbench.editor.labelFormat": "short", "workbench.editor.labelFormat": "short",
"eslint.workingDirectories": [{ "directory": "apps/web", "changeProcessCWD": true }] "eslint.workingDirectories": [{ "directory": "apps/web", "changeProcessCWD": true }],
"eslint.validate": [
"javascript",
"javascriptreact",
"json",
"typescript",
"typescriptreact",
"yaml"
],
"eslint.lintTask.enable": true
} }

View File

@ -1,5 +1,8 @@
.next .next
public public
*.config.js apollo.config.js
mocks mocks
graphql graphql/crm.schema.graphql
graphql/crm.types.ts
package.json
next-env.d.ts

View File

@ -1,6 +1,6 @@
module.exports = { module.exports = {
root: true, root: true,
extends: ['custom'], extends: ['custom', 'custom/rules'],
parserOptions: { parserOptions: {
project: './tsconfig.json', project: './tsconfig.json',
tsconfigRootDir: __dirname, tsconfigRootDir: __dirname,

View File

@ -1,4 +1,3 @@
/* eslint-disable object-curly-newline */
import type { FormTabRows } from '../../lib/render-rows'; import type { FormTabRows } from '../../lib/render-rows';
export const id = 'add-product'; export const id = 'add-product';

View File

@ -6,7 +6,7 @@ function Insurance() {
} }
export default { export default {
Component: Insurance,
id, id,
title, title,
Component: Insurance,
}; };

View File

@ -1,4 +1,3 @@
/* eslint-disable object-curly-newline */
import type { FormTabRows } from '../../lib/render-rows'; import type { FormTabRows } from '../../lib/render-rows';
export const id = 'create-kp'; export const id = 'create-kp';

View File

@ -6,7 +6,7 @@ function CreateKP() {
} }
export default { export default {
Component: CreateKP,
id, id,
title, title,
Component: CreateKP,
}; };

View File

@ -1,6 +1,6 @@
/* eslint-disable import/prefer-default-export */ /* eslint-disable canonical/sort-keys */
import type { ColumnsType } from 'antd/lib/table';
import type { Risk } from './types'; import type { Risk } from './types';
import type { ColumnsType } from 'antd/lib/table';
export const columns: ColumnsType<Risk> = [ export const columns: ColumnsType<Risk> = [
{ {

View File

@ -1,11 +1,11 @@
import { columns } from './config';
import { useStore } from '@/stores/hooks';
import { toJS } from 'mobx'; import { toJS } from 'mobx';
import { observer } from 'mobx-react-lite'; import { observer } from 'mobx-react-lite';
import { useStore } from 'stores/hooks';
import styled from 'styled-components'; import styled from 'styled-components';
import { Flex } from 'ui'; import { Flex } from 'ui';
import Alert from 'ui/elements/Alert'; import Alert from 'ui/elements/Alert';
import Table from 'ui/elements/Table'; import Table from 'ui/elements/Table';
import { columns } from './config';
const Grid = styled(Flex)` const Grid = styled(Flex)`
flex-direction: column; flex-direction: column;
@ -23,7 +23,7 @@ const Validation = observer(() => {
return null; return null;
}); });
const FinGAPTable = observer(() => { const FinGAP = observer(() => {
const { $tables } = useStore(); const { $tables } = useStore();
const { fingap } = $tables; const { fingap } = $tables;
@ -35,7 +35,6 @@ const FinGAPTable = observer(() => {
columns={columns} columns={columns}
dataSource={dataSource} dataSource={dataSource}
rowSelection={{ rowSelection={{
type: 'checkbox',
onChange: (_, selectedRows) => { onChange: (_, selectedRows) => {
const selectedKeys = selectedRows.reduce((acc, row) => { const selectedKeys = selectedRows.reduce((acc, row) => {
acc.push(row.key); acc.push(row.key);
@ -47,6 +46,7 @@ const FinGAPTable = observer(() => {
fingap.setSelectedKeys(selectedKeys); fingap.setSelectedKeys(selectedKeys);
}, },
selectedRowKeys, selectedRowKeys,
type: 'checkbox',
}} }}
pagination={false} pagination={false}
size="small" size="small"
@ -57,11 +57,11 @@ const FinGAPTable = observer(() => {
); );
}); });
export default function () { export default function FinGAPTable() {
return ( return (
<Grid> <Grid>
<Validation /> <Validation />
<FinGAPTable /> <FinGAP />
</Grid> </Grid>
); );
} }

View File

@ -1,4 +1,4 @@
import type { RiskSchema } from 'config/schema/fingap'; import type { RiskSchema } from '@/config/schema/fingap';
import type { z } from 'zod'; import type { z } from 'zod';
export type Risk = z.infer<typeof RiskSchema>; export type Risk = z.infer<typeof RiskSchema>;

View File

@ -1,8 +1,8 @@
import { observer } from 'mobx-react-lite';
import type { ComponentType } from 'react';
import { useRow } from 'stores/tables/insurance/hooks';
import { useInsuranceValue } from './hooks'; import { useInsuranceValue } from './hooks';
import type { Values } from './types'; import type { Values } from './types';
import { useRow } from '@/stores/tables/insurance/hooks';
import { observer } from 'mobx-react-lite';
import type { ComponentType } from 'react';
export function buildOptionComponent<T>( export function buildOptionComponent<T>(
key: string, key: string,
@ -16,7 +16,7 @@ export function buildOptionComponent<T>(
const statuses = getStatus(valueName); const statuses = getStatus(valueName);
return ( return (
<Component value={value} options={options} setValue={setValue} status={statuses} {...props} /> <Component options={options} setValue={setValue} status={statuses} value={value} {...props} />
); );
}); });
} }
@ -31,6 +31,6 @@ export function buildValueComponent<T>(
const { getStatus } = useRow(key); const { getStatus } = useRow(key);
const statuses = getStatus(valueName); const statuses = getStatus(valueName);
return <Component value={value} setValue={setValue} status={statuses} {...props} />; return <Component setValue={setValue} status={statuses} value={value} {...props} />;
}); });
} }

View File

@ -1,11 +1,11 @@
/* eslint-disable import/prefer-default-export */ /* eslint-disable canonical/sort-keys */
import { buildOptionComponent, buildValueComponent } from './builders';
import type * as Insurance from './types';
import { MAX_INSURANCE } from '@/constants/values';
import type { ColumnsType } from 'antd/lib/table'; import type { ColumnsType } from 'antd/lib/table';
import { MAX_INSURANCE } from 'constants/values';
import { formatter, parser } from 'tools/number'; import { formatter, parser } from 'tools/number';
import InputNumber from 'ui/elements/InputNumber'; import InputNumber from 'ui/elements/InputNumber';
import Select from 'ui/elements/Select'; import Select from 'ui/elements/Select';
import { buildOptionComponent, buildValueComponent } from './builders';
import type * as Insurance from './types';
export const columns: ColumnsType<Insurance.RowValues> = [ export const columns: ColumnsType<Insurance.RowValues> = [
{ {
@ -21,7 +21,7 @@ export const columns: ColumnsType<Insurance.RowValues> = [
render: (_, record) => { render: (_, record) => {
const Component = buildOptionComponent(record.key, Select, 'insuranceCompany'); const Component = buildOptionComponent(record.key, Select, 'insuranceCompany');
return <Component showSearch optionFilterProp="label" />; return <Component optionFilterProp="label" showSearch />;
}, },
}, },
{ {
@ -43,13 +43,13 @@ export const columns: ColumnsType<Insurance.RowValues> = [
return ( return (
<Component <Component
min={0}
max={MAX_INSURANCE}
step={1000}
precision={2}
parser={parser}
formatter={formatter}
addonAfter="₽" addonAfter="₽"
formatter={formatter}
max={MAX_INSURANCE}
min={0}
parser={parser}
precision={2}
step={1_000}
/> />
); );
}, },

View File

@ -1,6 +1,5 @@
/* eslint-disable import/prefer-default-export */ import { useRow } from '@/stores/tables/insurance/hooks';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { useRow } from 'stores/tables/insurance/hooks';
import { useDebouncedCallback } from 'use-debounce'; import { useDebouncedCallback } from 'use-debounce';
export function useInsuranceValue(key, valueName) { export function useInsuranceValue(key, valueName) {
@ -8,24 +7,19 @@ export function useInsuranceValue(key, valueName) {
const storeValue = row.getValue(valueName); const storeValue = row.getValue(valueName);
function setStoreValue(value) { function setStoreValue(val) {
return row.setValue(valueName, value); return row.setValue(valueName, val);
} }
const [value, setValue] = useState(storeValue); const [value, setValue] = useState(storeValue);
// eslint-disable-next-line object-curly-newline const debouncedSetStoreValue = useDebouncedCallback(setStoreValue, 350, { maxWait: 1_000 });
const debouncedSetStoreValue = useDebouncedCallback(setStoreValue, 350, { maxWait: 1000 });
useEffect( useEffect(() => {
() => {
if (storeValue !== value) { if (storeValue !== value) {
debouncedSetStoreValue(value); debouncedSetStoreValue(value);
} }
}, }, [value]);
// eslint-disable-next-line react-hooks/exhaustive-deps
[value]
);
useEffect(() => { useEffect(() => {
setValue(storeValue); setValue(storeValue);

View File

@ -1,10 +1,10 @@
import { columns } from './config';
import { useStore } from '@/stores/hooks';
import { observer } from 'mobx-react-lite'; import { observer } from 'mobx-react-lite';
import { useStore } from 'stores/hooks';
import styled from 'styled-components'; import styled from 'styled-components';
import { Flex } from 'ui'; import { Flex } from 'ui';
import Alert from 'ui/elements/Alert'; import Alert from 'ui/elements/Alert';
import Table from 'ui/elements/Table'; import Table from 'ui/elements/Table';
import { columns } from './config';
const Grid = styled(Flex)` const Grid = styled(Flex)`
flex-direction: column; flex-direction: column;
@ -28,7 +28,7 @@ const Validation = observer(() => {
return null; return null;
}); });
const InsuranceTable = observer(() => { const Insurance = observer(() => {
const store = useStore(); const store = useStore();
const { values } = store.$tables.insurance; const { values } = store.$tables.insurance;
@ -48,11 +48,11 @@ const InsuranceTable = observer(() => {
); );
}); });
export default function () { export default function InsuranceTable() {
return ( return (
<Grid> <Grid>
<Validation /> <Validation />
<InsuranceTable /> <Insurance />
</Grid> </Grid>
); );
} }

View File

@ -1,4 +1,4 @@
import type { KeysSchema, RowSchema } from 'config/schema/insurance'; import type { KeysSchema, RowSchema } from '@/config/schema/insurance';
import type { BaseOption, Status } from 'ui/elements/types'; import type { BaseOption, Status } from 'ui/elements/types';
import type { z } from 'zod'; import type { z } from 'zod';
@ -9,7 +9,7 @@ export type RowValues = z.infer<typeof RowSchema>;
export type Values = Exclude<keyof RowValues, 'key'>; export type Values = Exclude<keyof RowValues, 'key'>;
export type RowOptions = { export type RowOptions = {
[ValueName in Values]: BaseOption<RowValues[ValueName]>[]; [ValueName in Values]: Array<BaseOption<RowValues[ValueName]>>;
}; };
export type RowStatuses = Record<Values, Status>; export type RowStatuses = Record<Values, Status>;

View File

@ -1,8 +1,8 @@
import { Flex } from 'ui';
import renderFormRows from '../../lib/render-rows'; import renderFormRows from '../../lib/render-rows';
import { id, rows, title } from './config'; import { id, rows, title } from './config';
import FinGAPTable from './FinGAPTable'; import FinGAPTable from './FinGAPTable';
import InsuranceTable from './InsuranceTable'; import InsuranceTable from './InsuranceTable';
import { Flex } from 'ui';
function Insurance() { function Insurance() {
const renderedRows = renderFormRows(rows); const renderedRows = renderFormRows(rows);
@ -17,7 +17,7 @@ function Insurance() {
} }
export default { export default {
Component: Insurance,
id, id,
title, title,
Component: Insurance,
}; };

View File

@ -1,4 +1,3 @@
/* eslint-disable object-curly-newline */
import type { FormTabRows } from '../../lib/render-rows'; import type { FormTabRows } from '../../lib/render-rows';
export const id = 'leasing'; export const id = 'leasing';

View File

@ -6,7 +6,7 @@ function Leasing() {
} }
export default { export default {
Component: Leasing,
id, id,
title, title,
Component: Leasing,
}; };

View File

@ -1,4 +1,3 @@
/* eslint-disable object-curly-newline */
import type { FormTabRows } from '../../lib/render-rows'; import type { FormTabRows } from '../../lib/render-rows';
export const id = 'leasing-object'; export const id = 'leasing-object';

View File

@ -6,7 +6,7 @@ function LeasingObject() {
} }
export default { export default {
Component: LeasingObject,
id, id,
title, title,
Component: LeasingObject,
}; };

View File

@ -1,8 +1,8 @@
import { observer } from 'mobx-react-lite';
import { useStore } from 'stores/hooks';
import { Flex } from 'ui';
import elementsRender from '../../config/elements-render'; import elementsRender from '../../config/elements-render';
import { elements } from './config'; import { elements } from './config';
import { useStore } from '@/stores/hooks';
import { observer } from 'mobx-react-lite';
import { Flex } from 'ui';
function PaymentsParams() { function PaymentsParams() {
const renderedElements = elements.map((elementName) => { const renderedElements = elements.map((elementName) => {

View File

@ -1,14 +1,13 @@
/* eslint-disable import/prefer-default-export */ import { usePaymentValue } from './hooks';
import { useRowStatus } from '@/stores/tables/payments/hooks';
import { observer } from 'mobx-react-lite'; import { observer } from 'mobx-react-lite';
import type { ComponentType } from 'react'; import type { ComponentType } from 'react';
import { useRowStatus } from 'stores/tables/payments/hooks';
import { usePaymentValue } from './hooks';
export function buildValueComponent<T>(index: number, Component: ComponentType<T>) { export function buildValueComponent<T>(index: number, Component: ComponentType<T>) {
return observer((props: T) => { return observer((props: T) => {
const [value, setValue] = usePaymentValue(index); const [value, setValue] = usePaymentValue(index);
const status = useRowStatus(index); const status = useRowStatus(index);
return <Component value={value} setValue={setValue} status={status} {...props} />; return <Component setValue={setValue} status={status} value={value} {...props} />;
}); });
} }

View File

@ -1,9 +1,8 @@
/* eslint-disable import/prefer-default-export */ /* eslint-disable canonical/sort-keys */
import { buildValueComponent } from './builders';
import type { ColumnsType } from 'antd/lib/table'; import type { ColumnsType } from 'antd/lib/table';
import InputNumber from 'ui/elements/InputNumber'; import InputNumber from 'ui/elements/InputNumber';
import { buildValueComponent } from './builders';
type Payment = { type Payment = {
key: number; key: number;
num: number; num: number;
@ -27,10 +26,10 @@ export const columns: ColumnsType<Payment> = [
return ( return (
<Component <Component
min={payment.num === 0 ? 0 : 0.01}
max={100} max={100}
step={1} min={payment.num === 0 ? 0 : 0.01}
precision={payment.num === 0 ? 4 : 2} precision={payment.num === 0 ? 4 : 2}
step={1}
/> />
); );
}, },

View File

@ -1,24 +1,18 @@
/* eslint-disable import/prefer-default-export */ import { useRowValue } from '@/stores/tables/payments/hooks';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { useRowValue } from 'stores/tables/payments/hooks';
import { useDebouncedCallback } from 'use-debounce'; import { useDebouncedCallback } from 'use-debounce';
export function usePaymentValue(index) { export function usePaymentValue(index) {
const [storeValue, setStoreValue] = useRowValue(index); const [storeValue, setStoreValue] = useRowValue(index);
const [value, setValue] = useState(storeValue); const [value, setValue] = useState(storeValue);
// eslint-disable-next-line object-curly-newline const debouncedSetStoreValue = useDebouncedCallback(setStoreValue, 350, { maxWait: 1_000 });
const debouncedSetStoreValue = useDebouncedCallback(setStoreValue, 350, { maxWait: 1000 });
useEffect( useEffect(() => {
() => {
if (storeValue !== value) { if (storeValue !== value) {
debouncedSetStoreValue(value); debouncedSetStoreValue(value);
} }
}, }, [value]);
// eslint-disable-next-line react-hooks/exhaustive-deps
[value]
);
useEffect(() => { useEffect(() => {
setValue(storeValue); setValue(storeValue);

View File

@ -1,12 +1,12 @@
import { columns } from './config';
import { useStore } from '@/stores/hooks';
import { min } from '@/styles/mq';
import { computed } from 'mobx'; import { computed } from 'mobx';
import { observer } from 'mobx-react-lite'; import { observer } from 'mobx-react-lite';
import { useStore } from 'stores/hooks';
import styled from 'styled-components'; import styled from 'styled-components';
import { min } from 'styles/mq';
import Alert from 'ui/elements/Alert'; import Alert from 'ui/elements/Alert';
import Table from 'ui/elements/Table'; import Table from 'ui/elements/Table';
import { Box, Flex } from 'ui/grid'; import { Box, Flex } from 'ui/grid';
import { columns } from './config';
const Grid = styled(Flex)` const Grid = styled(Flex)`
flex-direction: column; flex-direction: column;

View File

@ -1,8 +1,8 @@
import { Box, Flex } from 'ui/grid';
import elementsRender from '../../config/elements-render'; import elementsRender from '../../config/elements-render';
import { id, title } from './config'; import { id, title } from './config';
import PaymentsParams from './PaymentsParams'; import PaymentsParams from './PaymentsParams';
import PaymentsTable from './PaymentsTable'; import PaymentsTable from './PaymentsTable';
import { Box, Flex } from 'ui/grid';
function Payments() { function Payments() {
const radioGraphType = elementsRender.radioGraphType.render(); const radioGraphType = elementsRender.radioGraphType.render();
@ -12,8 +12,8 @@ function Payments() {
<Box <Box
sx={{ sx={{
display: 'grid', display: 'grid',
gridTemplateColumns: ['1fr', '1fr', '1fr 1fr'],
gap: '10px', gap: '10px',
gridTemplateColumns: ['1fr', '1fr', '1fr 1fr'],
}} }}
> >
{radioGraphType} {radioGraphType}
@ -25,7 +25,7 @@ function Payments() {
} }
export default { export default {
Component: Payments,
id, id,
title, title,
Component: Payments,
}; };

View File

@ -1,4 +1,3 @@
/* eslint-disable object-curly-newline */
import type { FormTabRows } from '../../lib/render-rows'; import type { FormTabRows } from '../../lib/render-rows';
export const id = 'supplier-agent'; export const id = 'supplier-agent';

View File

@ -6,7 +6,7 @@ function Leasing() {
} }
export default { export default {
Component: Leasing,
id, id,
title, title,
Component: Leasing,
}; };

View File

@ -1,7 +1,3 @@
import Background from 'Components/Layout/Background';
import styled from 'styled-components';
import { min } from 'styles/mq';
import Tabs from 'ui/elements/layout/Tabs';
import AddProduct from './AddProduct'; import AddProduct from './AddProduct';
import CreateKP from './CreateKP'; import CreateKP from './CreateKP';
import Insurance from './Insurance'; import Insurance from './Insurance';
@ -9,6 +5,10 @@ import Leasing from './Leasing';
import LeasingObject from './LeasingObject'; import LeasingObject from './LeasingObject';
import Payments from './Payments'; import Payments from './Payments';
import SupplierAgent from './SupplierAgent'; import SupplierAgent from './SupplierAgent';
import Background from '@/Components/Layout/Background';
import { min } from '@/styles/mq';
import styled from 'styled-components';
import Tabs from 'ui/elements/layout/Tabs';
const formTabs = [Leasing, Payments, LeasingObject, SupplierAgent, Insurance, AddProduct, CreateKP]; const formTabs = [Leasing, Payments, LeasingObject, SupplierAgent, Insurance, AddProduct, CreateKP];

View File

@ -1,5 +1,3 @@
/* eslint-disable import/prefer-default-export */
/* eslint-disable object-curly-newline */
import type { FormTabRows } from '../lib/render-rows'; import type { FormTabRows } from '../lib/render-rows';
const defaultRowStyle = { gridTemplateColumns: '1fr' }; const defaultRowStyle = { gridTemplateColumns: '1fr' };

View File

@ -1,8 +1,8 @@
import Background from 'Components/Layout/Background';
import styled from 'styled-components';
import { min } from 'styles/mq';
import renderFormRows from '../lib/render-rows'; import renderFormRows from '../lib/render-rows';
import { rows } from './config'; import { rows } from './config';
import Background from '@/Components/Layout/Background';
import { min } from '@/styles/mq';
import styled from 'styled-components';
const Wrapper = styled(Background)` const Wrapper = styled(Background)`
padding: 4px 10px; padding: 4px 10px;

View File

@ -1,7 +1,7 @@
import * as CRMTypes from '@/graphql/crm.types';
import { useStore } from '@/stores/hooks';
import { useQuery } from '@apollo/client'; import { useQuery } from '@apollo/client';
import * as CRMTypes from 'graphql/crm.types';
import { observer } from 'mobx-react-lite'; import { observer } from 'mobx-react-lite';
import { useStore } from 'stores/hooks';
const CurrencyAddon = observer(() => { const CurrencyAddon = observer(() => {
const { $calculation } = useStore(); const { $calculation } = useStore();
@ -9,10 +9,11 @@ const CurrencyAddon = observer(() => {
const currencyid = $calculation.element('selectSupplierCurrency').getValue(); const currencyid = $calculation.element('selectSupplierCurrency').getValue();
const { data } = useQuery(CRMTypes.GetTransactionCurrencyDocument, { const { data } = useQuery(CRMTypes.GetTransactionCurrencyDocument, {
skip: !currencyid,
variables: { variables: {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
currencyid: currencyid!, currencyid: currencyid!,
}, },
skip: !currencyid,
}); });
return <span>{data?.transactioncurrency?.currencysymbol}</span>; return <span>{data?.transactioncurrency?.currencysymbol}</span>;

View File

@ -1,8 +1,7 @@
/* eslint-disable react/jsx-no-bind */ import type { Elements } from '../config/map/actions';
import { useStatus } from '@/stores/calculation/statuses/hooks';
import { observer } from 'mobx-react-lite'; import { observer } from 'mobx-react-lite';
import type { ComponentType } from 'react'; import type { ComponentType } from 'react';
import { useStatus } from 'stores/calculation/statuses/hooks';
import type { Elements } from '../config/map/actions';
type BuilderProps = { type BuilderProps = {
elementName: Elements; elementName: Elements;
@ -18,8 +17,8 @@ export default function buildAction<T>(
return ( return (
<Component <Component
action={() => import(`process/${actionName}`).then((module) => module.default())}
status={status} status={status}
action={() => import(`process/${actionName}`).then((m) => m.default())}
{...props} {...props}
/> />
); );

View File

@ -1,11 +1,11 @@
import { observer } from 'mobx-react-lite';
import type { ComponentType } from 'react';
import { useOptions } from 'stores/calculation/options/hooks';
import { useStatus } from 'stores/calculation/statuses/hooks';
import { useValidation } from 'stores/calculation/validation/hooks';
import type { Values } from 'stores/calculation/values/types';
import type { Elements } from '../config/map/values'; import type { Elements } from '../config/map/values';
import { useStoreValue } from './hooks'; import { useStoreValue } from './hooks';
import { useOptions } from '@/stores/calculation/options/hooks';
import { useStatus } from '@/stores/calculation/statuses/hooks';
import { useValidation } from '@/stores/calculation/validation/hooks';
import type { Values } from '@/stores/calculation/values/types';
import { observer } from 'mobx-react-lite';
import type { ComponentType } from 'react';
type BuilderProps = { type BuilderProps = {
elementName: Elements; elementName: Elements;
@ -24,12 +24,12 @@ export default function buildOptions<T>(
return ( return (
<Component <Component
value={value}
setValue={setValue}
options={options}
status={status}
isValid={isValid}
help={help} help={help}
isValid={isValid}
options={options}
setValue={setValue}
status={status}
value={value}
{...props} {...props}
/> />
); );

View File

@ -1,9 +1,9 @@
import type { Elements } from '../config/map/values';
import { useStatus } from '@/stores/calculation/statuses/hooks';
import { useValue } from '@/stores/calculation/values/hooks';
import type { Values } from '@/stores/calculation/values/types';
import { observer } from 'mobx-react-lite'; import { observer } from 'mobx-react-lite';
import type { ComponentType } from 'react'; import type { ComponentType } from 'react';
import { useStatus } from 'stores/calculation/statuses/hooks';
import { useValue } from 'stores/calculation/values/hooks';
import type { Values } from 'stores/calculation/values/types';
import type { Elements } from '../config/map/values';
type BuilderProps = { type BuilderProps = {
elementName: Elements; elementName: Elements;
@ -18,6 +18,6 @@ export default function buildReadonly<T>(
const [value] = useValue(valueName); const [value] = useValue(valueName);
const status = useStatus(elementName); const status = useStatus(elementName);
return <Component value={value} status={status} readOnly {...props} />; return <Component readOnly status={status} value={value} {...props} />;
}); });
} }

View File

@ -1,10 +1,10 @@
import { observer } from 'mobx-react-lite';
import type { ComponentType } from 'react';
import { useStatus } from 'stores/calculation/statuses/hooks';
import { useValidation } from 'stores/calculation/validation/hooks';
import type { Values } from 'stores/calculation/values/types';
import type { Elements } from '../config/map/values'; import type { Elements } from '../config/map/values';
import { useStoreValue } from './hooks'; import { useStoreValue } from './hooks';
import { useStatus } from '@/stores/calculation/statuses/hooks';
import { useValidation } from '@/stores/calculation/validation/hooks';
import type { Values } from '@/stores/calculation/values/types';
import { observer } from 'mobx-react-lite';
import type { ComponentType } from 'react';
export type BuilderProps = { export type BuilderProps = {
elementName: Elements; elementName: Elements;
@ -22,11 +22,11 @@ export default function buildValue<T>(
return ( return (
<Component <Component
value={value} help={help}
isValid={isValid}
setValue={setValue} setValue={setValue}
status={status} status={status}
isValid={isValid} value={value}
help={help}
{...props} {...props}
/> />
); );

View File

@ -1,24 +1,18 @@
/* eslint-disable import/prefer-default-export */ import { useValue } from '@/stores/calculation/values/hooks';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { useValue } from 'stores/calculation/values/hooks';
import { useDebouncedCallback } from 'use-debounce'; import { useDebouncedCallback } from 'use-debounce';
export function useStoreValue(valueName) { export function useStoreValue(valueName) {
const [storeValue, setStoreValue] = useValue(valueName); const [storeValue, setStoreValue] = useValue(valueName);
const [value, setValue] = useState(storeValue); const [value, setValue] = useState(storeValue);
// eslint-disable-next-line object-curly-newline const debouncedSetStoreValue = useDebouncedCallback(setStoreValue, 350, { maxWait: 1_000 });
const debouncedSetStoreValue = useDebouncedCallback(setStoreValue, 350, { maxWait: 1000 });
useEffect( useEffect(() => {
() => {
if (storeValue !== value) { if (storeValue !== value) {
debouncedSetStoreValue(value); debouncedSetStoreValue(value);
} }
}, }, [value]);
// eslint-disable-next-line react-hooks/exhaustive-deps
[value]
);
useEffect(() => { useEffect(() => {
setValue(storeValue); setValue(storeValue);

View File

@ -1,9 +1,11 @@
import type { ComponentProps } from 'react'; /* eslint-disable jsdoc/multiline-blocks */
import * as e from 'ui/elements'; /* eslint-disable canonical/sort-keys */
import type { Elements as ActionElements } from './map/actions'; import type { Elements as ActionElements } from './map/actions';
import type { Elements as ValuesElements } from './map/values'; import type { Elements as ValuesElements } from './map/values';
import type { ComponentProps } from 'react';
import * as e from 'ui/elements';
function wrapComponentsMap<C, T extends Record<ValuesElements | ActionElements, C>>(arg: T) { function wrapComponentsMap<C, T extends Record<ActionElements | ValuesElements, C>>(arg: T) {
return arg; return arg;
} }

View File

@ -1,9 +1,11 @@
import { MAX_FRANCHISE, MAX_LEASING_PERIOD } from 'constants/values'; /* eslint-disable jsdoc/multiline-blocks */
/* eslint-disable canonical/sort-keys */
import CurrencyAddon from '../addons/currency-addon';
import type { ElementsProps } from './elements-components';
import { MAX_FRANCHISE, MAX_LEASING_PERIOD } from '@/constants/values';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { formatter, formatterExtra, parser } from 'tools/number'; import { formatter, formatterExtra, parser } from 'tools/number';
import { DownloadOutlined } from 'ui/elements/icons'; import { DownloadOutlined } from 'ui/elements/icons';
import CurrencyAddon from '../addons/currency-addon';
import type { ElementsProps } from './elements-components';
const props: Partial<ElementsProps> = { const props: Partial<ElementsProps> = {
tbxLeaseObjectPrice: { tbxLeaseObjectPrice: {
@ -197,7 +199,7 @@ const props: Partial<ElementsProps> = {
}, },
tbxEngineVolume: { tbxEngineVolume: {
min: 0, min: 0,
max: 99.9999, max: 99.999_9,
step: 0.5, step: 0.5,
precision: 4, precision: 4,
parser, parser,
@ -354,7 +356,7 @@ const props: Partial<ElementsProps> = {
tbxIRR_Perc: { tbxIRR_Perc: {
min: 0, min: 0,
max: 500, max: 500,
step: 0.0001, step: 0.000_1,
precision: 6, precision: 6,
parser, parser,
formatter: formatterExtra, formatter: formatterExtra,

View File

@ -1,4 +1,3 @@
/* eslint-disable object-curly-newline */
import type map from '../map'; import type map from '../map';
import overrideRender from './override'; import overrideRender from './override';
import render from './render'; import render from './render';

View File

@ -1,10 +1,3 @@
/* eslint-disable object-curly-newline */
import { Container, Head } from 'Components/Layout/Element';
import { observer } from 'mobx-react-lite';
import type { ComponentProps } from 'react';
import { useStore } from 'stores/hooks';
import Link from 'ui/elements/Link';
import Tooltip from 'ui/elements/Tooltip';
import buildReadonly from '../../builders/build-readonly'; import buildReadonly from '../../builders/build-readonly';
import components from '../elements-components'; import components from '../elements-components';
import elementsProps from '../elements-props'; import elementsProps from '../elements-props';
@ -12,6 +5,12 @@ import titles from '../elements-titles';
import types from '../elements-types'; import types from '../elements-types';
import map from '../map'; import map from '../map';
import type { RenderProps } from './types'; import type { RenderProps } from './types';
import { Container, Head } from '@/Components/Layout/Element';
import { useStore } from '@/stores/hooks';
import { observer } from 'mobx-react-lite';
import type { ComponentProps } from 'react';
import Link from 'ui/elements/Link';
import Tooltip from 'ui/elements/Tooltip';
const defaultLinkProps: ComponentProps<typeof Link> = { const defaultLinkProps: ComponentProps<typeof Link> = {
text: 'Открыть в CRM', text: 'Открыть в CRM',
@ -19,6 +18,31 @@ const defaultLinkProps: ComponentProps<typeof Link> = {
}; };
const overrideRender: Partial<Record<keyof typeof map, RenderProps>> = { const overrideRender: Partial<Record<keyof typeof map, RenderProps>> = {
selectHighSeasonStart: {
render: () => {
const elementName = 'selectHighSeasonStart';
const title = titles.selectHighSeasonStart;
const valueName = map.selectHighSeasonStart;
const Component = components.selectHighSeasonStart;
const props = elementsProps.selectHighSeasonStart;
const { builder } = types.selectHighSeasonStart();
const Element = builder(Component, {
elementName,
valueName,
});
return (
<Tooltip placement="topLeft" title="С какого платежа начинается полный высокий сезон">
<Container>
<Head htmlFor={elementName} title={title} />
<Element {...props} id={elementName} />
</Container>
</Tooltip>
);
},
},
selectLead: { selectLead: {
render: () => { render: () => {
const elementName = 'selectLead'; const elementName = 'selectLead';
@ -41,9 +65,9 @@ const overrideRender: Partial<Record<keyof typeof map, RenderProps>> = {
return ( return (
<Container key={elementName}> <Container key={elementName}>
<Head <Head
addon={<LinkComponent {...defaultLinkProps} />}
htmlFor={elementName} htmlFor={elementName}
title={title} title={title}
addon={<LinkComponent {...defaultLinkProps} />}
/> />
<Element {...props} id={elementName} /> <Element {...props} id={elementName} />
</Container> </Container>
@ -73,9 +97,9 @@ const overrideRender: Partial<Record<keyof typeof map, RenderProps>> = {
return ( return (
<Container key={elementName}> <Container key={elementName}>
<Head <Head
addon={<LinkComponent {...defaultLinkProps} />}
htmlFor={elementName} htmlFor={elementName}
title={title} title={title}
addon={<LinkComponent {...defaultLinkProps} />}
/> />
<Element {...props} id={elementName} /> <Element {...props} id={elementName} />
</Container> </Container>
@ -105,9 +129,9 @@ const overrideRender: Partial<Record<keyof typeof map, RenderProps>> = {
return ( return (
<Container key={elementName}> <Container key={elementName}>
<Head <Head
addon={<LinkComponent {...defaultLinkProps} />}
htmlFor={elementName} htmlFor={elementName}
title={title} title={title}
addon={<LinkComponent {...defaultLinkProps} />}
/> />
<Element {...props} id={elementName} /> <Element {...props} id={elementName} />
</Container> </Container>
@ -115,56 +139,6 @@ const overrideRender: Partial<Record<keyof typeof map, RenderProps>> = {
}, },
}, },
tbxVehicleTaxInYear: {
render: () => {
const elementName = 'tbxVehicleTaxInYear';
const title = titles.tbxVehicleTaxInYear;
const valueName = map.tbxVehicleTaxInYear;
const Component = components.tbxVehicleTaxInYear;
const props = elementsProps.tbxVehicleTaxInYear;
const { builder } = types.tbxVehicleTaxInYear();
const Element = builder(Component, {
elementName,
valueName,
});
return (
<Tooltip title="Без учета налога на роскошь" placement="topLeft">
<Container>
<Head htmlFor={elementName} title={title} />
<Element {...props} id={elementName} />
</Container>
</Tooltip>
);
},
},
selectHighSeasonStart: {
render: () => {
const elementName = 'selectHighSeasonStart';
const title = titles.selectHighSeasonStart;
const valueName = map.selectHighSeasonStart;
const Component = components.selectHighSeasonStart;
const props = elementsProps.selectHighSeasonStart;
const { builder } = types.selectHighSeasonStart();
const Element = builder(Component, {
elementName,
valueName,
});
return (
<Tooltip title="С какого платежа начинается полный высокий сезон" placement="topLeft">
<Container>
<Head htmlFor={elementName} title={title} />
<Element {...props} id={elementName} />
</Container>
</Tooltip>
);
},
},
selectSeasonType: { selectSeasonType: {
render: () => { render: () => {
const elementName = 'selectSeasonType'; const elementName = 'selectSeasonType';
@ -203,6 +177,31 @@ const overrideRender: Partial<Record<keyof typeof map, RenderProps>> = {
); );
}, },
}, },
tbxVehicleTaxInYear: {
render: () => {
const elementName = 'tbxVehicleTaxInYear';
const title = titles.tbxVehicleTaxInYear;
const valueName = map.tbxVehicleTaxInYear;
const Component = components.tbxVehicleTaxInYear;
const props = elementsProps.tbxVehicleTaxInYear;
const { builder } = types.tbxVehicleTaxInYear();
const Element = builder(Component, {
elementName,
valueName,
});
return (
<Tooltip placement="topLeft" title="Без учета налога на роскошь">
<Container>
<Head htmlFor={elementName} title={title} />
<Element {...props} id={elementName} />
</Container>
</Tooltip>
);
},
},
}; };
export default overrideRender; export default overrideRender;

View File

@ -1,10 +1,9 @@
/* eslint-disable object-curly-newline */
import { Container, Head } from 'Components/Layout/Element';
import components from '../elements-components'; import components from '../elements-components';
import elementsProps from '../elements-props'; import elementsProps from '../elements-props';
import titles from '../elements-titles'; import titles from '../elements-titles';
import types from '../elements-types'; import types from '../elements-types';
import map from '../map'; import map from '../map';
import { Container, Head } from '@/Components/Layout/Element';
const render = Object.keys(map).reduce((acc, elementName) => { const render = Object.keys(map).reduce((acc, elementName) => {
const title = titles[elementName]; const title = titles[elementName];

View File

@ -1,7 +1,9 @@
/* eslint-disable jsdoc/multiline-blocks */
/* eslint-disable canonical/sort-keys */
import type { Elements as ActionElements } from './map/actions'; import type { Elements as ActionElements } from './map/actions';
import type { Elements as ValuesElements } from './map/values'; import type { Elements as ValuesElements } from './map/values';
const titles: Record<ValuesElements | ActionElements, string> = { const titles: Record<ActionElements | ValuesElements, string> = {
selectLead: 'Интерес', selectLead: 'Интерес',
selectOpportunity: 'Лизинговая сделка', selectOpportunity: 'Лизинговая сделка',
selectQuote: 'Предложение', selectQuote: 'Предложение',

View File

@ -1,13 +1,15 @@
/* eslint-disable jsdoc/multiline-blocks */
/* eslint-disable canonical/sort-keys */
import { buildAction, buildOptions, buildReadonly, buildValue } from '../builders'; import { buildAction, buildOptions, buildReadonly, buildValue } from '../builders';
import type { Elements as ActionElements } from './map/actions'; import type { Elements as ActionElements } from './map/actions';
import type { Elements as ValuesElements } from './map/values'; import type { Elements as ValuesElements } from './map/values';
type ElementTypes = 'Value' | 'Readonly' | 'Options' | 'Action'; type ElementTypes = 'Action' | 'Options' | 'Readonly' | 'Value';
type Builders = typeof buildValue | typeof buildReadonly | typeof buildOptions | typeof buildAction; type Builders = typeof buildAction | typeof buildOptions | typeof buildReadonly | typeof buildValue;
type GetType = () => { type GetType = () => {
typeName: ElementTypes;
builder: Builders; builder: Builders;
typeName: ElementTypes;
}; };
function wrapTypeGetters<G extends GetType, E extends Record<ElementTypes, G>>(arg: E) { function wrapTypeGetters<G extends GetType, E extends Record<ElementTypes, G>>(arg: E) {
@ -33,7 +35,7 @@ const t = wrapTypeGetters({
}), }),
}); });
function wrapElementsTypes<T, E extends Record<ValuesElements | ActionElements, T>>(arg: E) { function wrapElementsTypes<T, E extends Record<ActionElements | ValuesElements, T>>(arg: E) {
return arg; return arg;
} }

View File

@ -1,4 +1,6 @@
import type { CalculationValues, Values } from 'stores/calculation/values/types'; /* eslint-disable jsdoc/multiline-blocks */
/* eslint-disable canonical/sort-keys */
import type { CalculationValues, Values } from '@/stores/calculation/values/types';
function wrapElementsMap<T extends Record<string, Values>>(arg: T) { function wrapElementsMap<T extends Record<string, Values>>(arg: T) {
return arg; return arg;

View File

@ -1,15 +1,19 @@
/* eslint-disable react/no-array-index-key */ /* eslint-disable react/no-array-index-key */
import Divider from 'ui/elements/layout/Divider';
import type { BoxProps } from 'ui/grid';
import { Box } from 'ui/grid';
import elementsRender from '../config/elements-render'; import elementsRender from '../config/elements-render';
import type { Elements as ActionElements } from '../config/map/actions'; import type { Elements as ActionElements } from '../config/map/actions';
import type { Elements as ValuesElements } from '../config/map/values'; import type { Elements as ValuesElements } from '../config/map/values';
import Divider from 'ui/elements/layout/Divider';
import type { BoxProps } from 'ui/grid';
import { Box } from 'ui/grid';
export type ElementsRow = [elements: (ValuesElements | ActionElements)[], style?: BoxProps['sx']]; export type ElementsRow = [
elements: Array<ActionElements | ValuesElements>,
style?: BoxProps['sx']
];
type DividerRow = { title: string }; type DividerRow = { title: string };
export type FormTabRows = Array<ElementsRow | DividerRow>; export type FormTabRows = Array<DividerRow | ElementsRow>;
function renderFormRows(rowsConfig: FormTabRows) { function renderFormRows(rowsConfig: FormTabRows) {
const rows = rowsConfig.map((row, i) => { const rows = rowsConfig.map((row, i) => {
@ -18,7 +22,6 @@ function renderFormRows(rowsConfig: FormTabRows) {
const renderedElements = elements.map((elementName) => { const renderedElements = elements.map((elementName) => {
const render = elementsRender[elementName]?.render; const render = elementsRender[elementName]?.render;
// eslint-disable-next-line object-curly-newline
return render({}); return render({});
}); });
@ -27,8 +30,8 @@ function renderFormRows(rowsConfig: FormTabRows) {
key={i.toString()} key={i.toString()}
sx={{ sx={{
display: 'grid', display: 'grid',
gridTemplateColumns: ['1fr', '1fr', 'repeat(3, 1fr)'],
gap: '10px', gap: '10px',
gridTemplateColumns: ['1fr', '1fr', 'repeat(3, 1fr)'],
...style, ...style,
}} }}
> >

View File

@ -1,4 +1,3 @@
/* eslint-disable import/prefer-default-export */
import Button from 'ui/elements/Button'; import Button from 'ui/elements/Button';
import Result from 'ui/elements/Result'; import Result from 'ui/elements/Result';

View File

@ -1,7 +1,7 @@
import { getUser } from '@/api/user/query';
import { min } from '@/styles/mq';
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { getUser } from 'api/user/query';
import styled from 'styled-components'; import styled from 'styled-components';
import { min } from 'styles/mq';
import { Flex } from 'ui'; import { Flex } from 'ui';
const UserText = styled.span` const UserText = styled.span`

View File

@ -1,5 +1,5 @@
import { min } from '@/styles/mq';
import styled from 'styled-components'; import styled from 'styled-components';
import { min } from 'styles/mq';
import { Box } from 'ui/grid'; import { Box } from 'ui/grid';
const Background = styled(Box)` const Background = styled(Box)`

View File

@ -1,6 +1,7 @@
/* eslint-disable func-style */
import { min } from '@/styles/mq';
import type { ReactNode } from 'react'; import type { ReactNode } from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import { min } from 'styles/mq';
import { Flex } from 'ui'; import { Flex } from 'ui';
const ElementTitle = styled.label` const ElementTitle = styled.label`
@ -23,12 +24,12 @@ export function Head({
addon, addon,
htmlFor, htmlFor,
}: { }: {
title: ReactNode;
addon?: ReactNode; addon?: ReactNode;
htmlFor: string; htmlFor: string;
title: ReactNode;
}) { }) {
return ( return (
<Flex flexDirection={['row']} justifyContent={['space-between']} alignItems={['center']}> <Flex alignItems={['center']} flexDirection={['row']} justifyContent={['space-between']}>
<ElementTitle htmlFor={htmlFor}>{title}</ElementTitle> <ElementTitle htmlFor={htmlFor}>{title}</ElementTitle>
{addon} {addon}
</Flex> </Flex>

View File

@ -1,9 +1,8 @@
/* eslint-disable import/no-unresolved */
import styled from 'styled-components';
import { min } from 'styles/mq';
import { Flex } from 'ui';
import Auth from './Auth'; import Auth from './Auth';
import Logo from './Logo'; import Logo from './Logo';
import { min } from '@/styles/mq';
import styled from 'styled-components';
import { Flex } from 'ui';
const HeaderContent = styled(Flex)` const HeaderContent = styled(Flex)`
flex-direction: row; flex-direction: row;
@ -16,7 +15,6 @@ const HeaderContent = styled(Flex)`
var(--color-tertiarty) 100% var(--color-tertiarty) 100%
); );
${'' /* height: 70px; */}
padding: 10px 12px; padding: 10px 12px;
${min('laptop')} { ${min('laptop')} {
padding: 10px 12px; padding: 10px 12px;

View File

@ -1,9 +1,10 @@
/* eslint-disable react/forbid-component-props */
import styles from './Logo.module.css';
import { min } from '@/styles/mq';
import Image from 'next/image'; import Image from 'next/image';
import logo from 'public/assets/images/logo-primary.svg'; import logo from 'public/assets/images/logo-primary.svg';
import styled from 'styled-components'; import styled from 'styled-components';
import { min } from 'styles/mq';
import { Flex } from 'ui'; import { Flex } from 'ui';
import styles from './Logo.module.css';
const ImageWrapper = styled.div` const ImageWrapper = styled.div`
width: 100px; width: 100px;

View File

@ -1,7 +1,5 @@
/* eslint-disable react/prop-types */
/* eslint-disable import/no-unresolved */
import { Flex } from 'ui';
import Header from './Header'; import Header from './Header';
import { Flex } from 'ui';
export default function Layout({ children }) { export default function Layout({ children }) {
return ( return (

View File

@ -1,7 +1,6 @@
/* eslint-disable import/prefer-default-export */ /* eslint-disable canonical/sort-keys */
import type { ColumnsType } from 'antd/lib/table';
import type { Payment } from './types'; import type { Payment } from './types';
import type { ColumnsType } from 'antd/lib/table';
export const columns: ColumnsType<Payment> = [ export const columns: ColumnsType<Payment> = [
{ {

View File

@ -1,9 +1,9 @@
import { MAX_LEASING_PERIOD } from 'constants/values'; import { columns } from './config';
import { MAX_LEASING_PERIOD } from '@/constants/values';
import { useStore } from '@/stores/hooks';
import { toJS } from 'mobx'; import { toJS } from 'mobx';
import { observer } from 'mobx-react-lite'; import { observer } from 'mobx-react-lite';
import { useStore } from 'stores/hooks';
import Table from 'ui/elements/Table'; import Table from 'ui/elements/Table';
import { columns } from './config';
const PaymentsTable = observer(() => { const PaymentsTable = observer(() => {
const { $results } = useStore(); const { $results } = useStore();
@ -26,7 +26,7 @@ const PaymentsTable = observer(() => {
}); });
export default { export default {
Component: PaymentsTable,
id: 'payments-table', id: 'payments-table',
title: 'Таблица платежей', title: 'Таблица платежей',
Component: PaymentsTable,
}; };

View File

@ -1,7 +1,7 @@
export type Payment = { export type Payment = {
key: string; key: string;
ndsCompensation: string;
num: number; num: number;
paymentSum: string; paymentSum: string;
ndsCompensation: string;
redemptionAmount: string; redemptionAmount: string;
}; };

View File

@ -1,29 +1,27 @@
/* eslint-disable object-curly-newline */ import type { Values } from '@/stores/results/types';
import type { Values } from 'stores/results/types';
export const id = 'output'; export const id = 'output';
export const title = 'Результаты'; export const title = 'Результаты';
export const titles: Record<Values, string> = { export const titles: Record<Values, string> = {
resultTotalGraphwithNDS: 'Итого по графику, с НДС', resultAB_FL: 'АВ ФЛ, без НДФЛ.',
resultPlPrice: 'Стоимость ПЛ с НДС', resultAB_UL: 'АВ ЮЛ, с НДС.',
resultPriceUpPr: 'Удорожание, год', resultBonusDopProd: 'Бонус МПЛ за доп.продукты, без НДФЛ',
resultBonusMPL: 'Бонус МПЛ за лизинг, без НДФЛ',
resultBonusSafeFinance: 'Бонус за Safe Finance без НДФЛ',
resultDopMPLLeasing: 'Доп.бонус МПЛ за лизинг, без НДФЛ',
resultDopProdSum: 'Общая сумма доп.продуктов',
resultFirstPayment: 'Первый платеж',
resultFirstPaymentRiskPolicy: 'Первый платеж по риск политике, %',
resultIRRGraphPerc: 'IRR по графику клиента, %', resultIRRGraphPerc: 'IRR по графику клиента, %',
resultIRRNominalPerc: 'IRR (номинал), %', resultIRRNominalPerc: 'IRR (номинал), %',
resultInsKasko: 'КАСКО, НС, ДГО в графике', resultInsKasko: 'КАСКО, НС, ДГО в графике',
resultInsOsago: 'ОСАГО в графике', resultInsOsago: 'ОСАГО в графике',
resultDopProdSum: 'Общая сумма доп.продуктов',
resultFirstPayment: 'Первый платеж',
resultLastPayment: 'Последний платеж', resultLastPayment: 'Последний платеж',
resultPlPrice: 'Стоимость ПЛ с НДС',
resultPriceUpPr: 'Удорожание, год',
resultTerm: 'Срок, мес.', resultTerm: 'Срок, мес.',
resultAB_FL: 'АВ ФЛ, без НДФЛ.', resultTotalGraphwithNDS: 'Итого по графику, с НДС',
resultAB_UL: 'АВ ЮЛ, с НДС.',
resultBonusMPL: 'Бонус МПЛ за лизинг, без НДФЛ',
resultDopMPLLeasing: 'Доп.бонус МПЛ за лизинг, без НДФЛ',
resultBonusDopProd: 'Бонус МПЛ за доп.продукты, без НДФЛ',
resultBonusSafeFinance: 'Бонус за Safe Finance без НДФЛ',
resultFirstPaymentRiskPolicy: 'Первый платеж по риск политике, %',
}; };
const moneyFormatters = Object.fromEntries( const moneyFormatters = Object.fromEntries(
@ -47,10 +45,9 @@ const moneyFormatters = Object.fromEntries(
] as Values[] ] as Values[]
).map((a) => [ ).map((a) => [
a, a,
// prettier-ignore
Intl.NumberFormat('ru', { Intl.NumberFormat('ru', {
style: 'currency',
currency: 'RUB', currency: 'RUB',
style: 'currency',
}).format, }).format,
]) ])
); );
@ -59,11 +56,10 @@ const percentFormatters = Object.fromEntries(
(['resultIRRGraphPerc', 'resultIRRNominalPerc', 'resultFirstPaymentRiskPolicy'] as Values[]).map( (['resultIRRGraphPerc', 'resultIRRNominalPerc', 'resultFirstPaymentRiskPolicy'] as Values[]).map(
(a) => [ (a) => [
a, a,
// prettier-ignore
Intl.NumberFormat('ru', { Intl.NumberFormat('ru', {
style: 'percent',
minimumFractionDigits: 2,
maximumFractionDigits: 2, maximumFractionDigits: 2,
minimumFractionDigits: 2,
style: 'percent',
}).format, }).format,
] ]
) )

View File

@ -1,12 +1,12 @@
import { Container, Head } from 'Components/Layout/Element'; import { formatters, id, title, titles } from './config';
import { Container, Head } from '@/Components/Layout/Element';
import { useStore } from '@/stores/hooks';
import { min } from '@/styles/mq';
import { toJS } from 'mobx'; import { toJS } from 'mobx';
import { observer } from 'mobx-react-lite'; import { observer } from 'mobx-react-lite';
import { useStore } from 'stores/hooks';
import styled from 'styled-components'; import styled from 'styled-components';
import { min } from 'styles/mq';
import Text from 'ui/elements/Text'; import Text from 'ui/elements/Text';
import { Box } from 'ui/grid'; import { Box } from 'ui/grid';
import { formatters, id, title, titles } from './config';
const Grid = styled(Box)` const Grid = styled(Box)`
display: grid; display: grid;
@ -40,7 +40,7 @@ const Results = observer(() => {
}); });
export default { export default {
Component: Results,
id, id,
title, title,
Component: Results,
}; };

View File

@ -1,5 +1,6 @@
/* eslint-disable react/jsx-key */
import { useStore } from '@/stores/hooks';
import { observer } from 'mobx-react-lite'; import { observer } from 'mobx-react-lite';
import { useStore } from 'stores/hooks';
import styled from 'styled-components'; import styled from 'styled-components';
import Alert from 'ui/elements/Alert'; import Alert from 'ui/elements/Alert';
import { Box, Flex } from 'ui/grid'; import { Box, Flex } from 'ui/grid';
@ -23,18 +24,16 @@ const AlertWrapper = styled(Box)`
`; `;
function getElementsErrors($calculation) { function getElementsErrors($calculation) {
const errors = Object.values($calculation.$validation).map((validation) => { return Object.values($calculation.$validation).map((validation) => {
const elementErrors = validation.getMessages(); const elementErrors = validation.getMessages();
const elementTitle = validation.params.err_title; const elementTitle = validation.params.err_title;
return elementErrors.map((error) => ( return elementErrors.map((error) => (
<AlertWrapper> <AlertWrapper>
<Alert key={error.name} type="error" showIcon message={Message(elementTitle, error)} /> <Alert type="error" showIcon message={Message(elementTitle, error)} />
</AlertWrapper> </AlertWrapper>
)); ));
}); });
return errors;
} }
function getPaymentsTableErrors($tables) { function getPaymentsTableErrors($tables) {
@ -50,9 +49,7 @@ function getInsuranceTableErrors($tables) {
const messages = insurance.validation.getMessages(); const messages = insurance.validation.getMessages();
const title = insurance.validation.params.err_title; const title = insurance.validation.params.err_title;
return messages.map((message) => ( return messages.map((text) => <Alert type="error" showIcon message={Message(title, text)} />);
<Alert type="error" showIcon message={Message(title, message)} />
));
} }
const Errors = observer(() => { const Errors = observer(() => {
@ -86,7 +83,7 @@ function Validation() {
} }
export default { export default {
Component: Validation,
id: 'validation', id: 'validation',
title: 'Ошибки', title: 'Ошибки',
Component: Validation,
}; };

View File

@ -1,10 +1,10 @@
import Background from 'Components/Layout/Background';
import styled from 'styled-components';
import { min } from 'styles/mq';
import Tabs from 'ui/elements/layout/Tabs';
import PaymentsTable from './PaymentsTable'; import PaymentsTable from './PaymentsTable';
import Results from './Results'; import Results from './Results';
import Validation from './Validation'; import Validation from './Validation';
import Background from '@/Components/Layout/Background';
import { min } from '@/styles/mq';
import styled from 'styled-components';
import Tabs from 'ui/elements/layout/Tabs';
const outputTabs = [PaymentsTable, Results, Validation]; const outputTabs = [PaymentsTable, Results, Validation];

View File

@ -1,8 +1,7 @@
/* eslint-disable import/prefer-default-export */ import type { RequestFinGAP, ResponseFinGAP } from './types';
import getUrls from '@/config/urls';
import type { QueryFunctionContext } from '@tanstack/react-query'; import type { QueryFunctionContext } from '@tanstack/react-query';
import axios from 'axios'; import axios from 'axios';
import getUrls from 'config/urls';
import type { RequestFinGAP, ResponseFinGAP } from './types';
const { URL_CORE_FINGAP } = getUrls(); const { URL_CORE_FINGAP } = getUrls();

View File

@ -5,17 +5,17 @@ export type PaymentRow = {
export type RequestFinGAP = { export type RequestFinGAP = {
calcType: number; calcType: number;
payments: Array<PaymentRow>; payments: PaymentRow[];
values: { values: {
plPrice: number;
discount: number; discount: number;
firstPayment: number; firstPayment: number;
leasingPeriod: number; leasingPeriod: number;
plPrice: number;
premiumPerc: number; premiumPerc: number;
}; };
}; };
export type ResponseFinGAP = { export type ResponseFinGAP = {
sum: number;
premium: number; premium: number;
sum: number;
}; };

View File

@ -1,14 +1,11 @@
/* eslint-disable import/prefer-default-export */
import type { AxiosRequestConfig } from 'axios';
import axios from 'axios';
import getUrls from 'config/urls';
import { love } from './tools'; import { love } from './tools';
import type { User } from './types'; import type { User } from './types';
import getUrls from '@/config/urls';
import type { AxiosRequestConfig } from 'axios';
import axios from 'axios';
const { URL_GET_USER } = getUrls(); const { URL_GET_USER } = getUrls();
export async function getUser(config: AxiosRequestConfig) { export async function getUser(config: AxiosRequestConfig) {
const user = await axios.get<User>(URL_GET_USER, config).then((res) => love(res.data)); return await axios.get<User>(URL_GET_USER, config).then((res) => love(res.data));
return user;
} }

View File

@ -1,14 +1,12 @@
/* eslint-disable import/prefer-default-export */
import { publicRuntimeConfigSchema } from 'config/schema/runtime-config';
import getConfig from 'next/config';
import type { User } from './types'; import type { User } from './types';
import { publicRuntimeConfigSchema } from '@/config/schema/runtime-config';
import getConfig from 'next/config';
const { publicRuntimeConfig } = getConfig(); const { publicRuntimeConfig } = getConfig();
const { USERS_SUPER } = publicRuntimeConfigSchema.parse(publicRuntimeConfig); const { USERS_SUPER } = publicRuntimeConfigSchema.parse(publicRuntimeConfig);
export function love(user: User) { export function love(user: User) {
const superUsers: string[] = JSON.parse(USERS_SUPER); const superUsers: string[] = JSON.parse(USERS_SUPER);
// eslint-disable-next-line no-param-reassign
if (superUsers?.includes(user.username)) user.displayName += '🧡'; if (superUsers?.includes(user.username)) user.displayName += '🧡';
return user; return user;

View File

@ -1,9 +1,9 @@
export type User = { export type User = {
displayName: string;
username: string;
department: string; department: string;
position: string; displayName: string;
mail: string;
domain: string; domain: string;
domainName: string; domainName: string;
mail: string;
position: string;
username: string;
}; };

View File

@ -5,12 +5,12 @@ module.exports = {
name: 'crmgraphql', name: 'crmgraphql',
localSchemaFile: `${__dirname}/graphql/crm.schema.graphql`, localSchemaFile: `${__dirname}/graphql/crm.schema.graphql`,
}, },
excludes: ['**/graphql/**/*.schema.graphql', '**/graphql/**/*.types.graphql'],
includes: [ includes: [
'**/pages/**/*', '**/pages/**/*',
'**/process/**/*', '**/process/**/*',
'**/Components/**/*', '**/Components/**/*',
'**/graphql/**/*.query.graphql', '**/graphql/**/*.query.graphql',
], ],
excludes: ['**/graphql/**/*.schema.graphql', '**/graphql/**/*.types.graphql'],
}, },
}; };

View File

@ -1,19 +1,17 @@
/* eslint-disable no-underscore-dangle */ import getUrls from '@/config/urls';
/* eslint-disable @typescript-eslint/naming-convention */
import { ApolloClient, InMemoryCache } from '@apollo/client'; import { ApolloClient, InMemoryCache } from '@apollo/client';
import getUrls from 'config/urls';
import { isServer } from 'tools/common'; import { isServer } from 'tools/common';
/** @type {import('@apollo/client').ApolloClient<NormalizedCacheObject>} */ /** @type {import('@apollo/client').ApolloClient<import('@apollo/client').NormalizedCacheObject>} */
let apolloClient; let apolloClient;
const { URL_CRM_GRAPHQL } = getUrls(); const { URL_CRM_GRAPHQL } = getUrls();
function createApolloClient() { function createApolloClient() {
return new ApolloClient({ return new ApolloClient({
cache: new InMemoryCache(),
ssrMode: isServer(), ssrMode: isServer(),
uri: URL_CRM_GRAPHQL, uri: URL_CRM_GRAPHQL,
cache: new InMemoryCache(),
}); });
} }

View File

@ -1,5 +1,6 @@
/* eslint-disable canonical/sort-keys */
import type { CalculationOptions } from '@/stores/calculation/options/types';
import { alphabetical } from 'radash'; import { alphabetical } from 'radash';
import type { CalculationOptions } from 'stores/calculation/options/types';
export const selectSeasonType = [ export const selectSeasonType = [
{ {

View File

@ -1,141 +1,141 @@
import type { CalculationStatuses } from 'stores/calculation/statuses/types'; import type { CalculationStatuses } from '@/stores/calculation/statuses/types';
const defaultStatuses: CalculationStatuses = { const defaultStatuses: CalculationStatuses = {
selectIndAgent: 'Default', btnCalculate: 'Default',
selectCalcBroker: 'Default', btnCreateKP: 'Default',
selectCalcFinDepartment: 'Default',
selectCalcDoubleAgent: 'Default',
selectClientType: 'Disabled',
tbxImporterRewardRub: 'Disabled',
tbxImporterRewardPerc: 'Disabled',
tbxMaxPriceChange: 'Disabled',
tbxCreditRate: 'Disabled',
selectRate: 'Disabled',
selectTarif: 'Disabled',
tbxVehicleTaxInLeasingPeriod: 'Disabled',
selectObjectTypeTax: 'Disabled',
selectLeaseObjectCategory: 'Disabled',
tbxINNForCalc: 'Disabled',
radioInfuranceOPF: 'Disabled',
tbxRedemptionPaymentSum: 'Disabled',
tbxLeaseObjectPriceWthtVAT: 'Disabled',
selectLead: 'Default',
selectOpportunity: 'Default',
selectQuote: 'Default',
cbxRecalcWithRevision: 'Default',
selectProduct: 'Default',
selectClientRisk: 'Default',
tbxLeaseObjectPrice: 'Default',
tbxVATInLeaseObjectPrice: 'Default',
tbxEngineHours: 'Default',
selectSupplierCurrency: 'Default',
tbxSupplierDiscountRub: 'Default',
tbxSupplierDiscountPerc: 'Default',
tbxLeasingPeriod: 'Default',
tbxFirstPaymentPerc: 'Default',
tbxFirstPaymentRub: 'Default',
tbxLastPaymentPerc: 'Default',
tbxLastPaymentRub: 'Default',
radioLastPaymentRule: 'Default',
radioBalanceHolder: 'Default',
radioGraphType: 'Default',
tbxParmentsDecreasePercent: 'Default',
selectSeasonType: 'Default',
selectHighSeasonStart: 'Default',
tbxComissionPerc: 'Default',
tbxComissionRub: 'Default',
tbxSaleBonus: 'Default',
tbxIRR_Perc: 'Default',
selectLeaseObjectType: 'Default',
radioDeliveryTime: 'Default',
labelDepreciationGroup: 'Default',
tbxLeaseObjectCount: 'Default',
cbxWithTrailer: 'Default',
cbxLeaseObjectUsed: 'Default',
tbxMaxMass: 'Default',
tbxCountSeats: 'Default',
tbxMaxSpeed: 'Default',
selectBrand: 'Default',
selectModel: 'Default',
selectConfiguration: 'Default',
tbxLeaseObjectYear: 'Default',
selectEngineType: 'Default',
tbxLeaseObjectMotorPower: 'Default',
tbxEngineVolume: 'Default',
selectLeaseObjectUseFor: 'Default',
selectDealer: 'Default',
selectDealerPerson: 'Default',
selectDealerRewardCondition: 'Default',
tbxDealerRewardSumm: 'Disabled',
selectDealerBroker: 'Default',
selectDealerBrokerRewardCondition: 'Default',
tbxDealerBrokerRewardSumm: 'Disabled',
selectIndAgentRewardCondition: 'Default',
tbxIndAgentRewardSumm: 'Disabled',
selectCalcDoubleAgentRewardCondition: 'Default',
tbxCalcDoubleAgentRewardSumm: 'Disabled',
selectCalcBrokerRewardCondition: 'Default',
tbxCalcBrokerRewardSum: 'Disabled',
selectFinDepartmentRewardCondtion: 'Default',
tbxFinDepartmentRewardSumm: 'Disabled',
selectGPSBrand: 'Default',
selectGPSModel: 'Default',
selectRegionRegistration: 'Default',
selectTownRegistration: 'Default',
radioInsKaskoType: 'Default',
cbxInsDecentral: 'Default',
tbxInsFranchise: 'Default',
cbxInsUnlimitDrivers: 'Default',
tbxInsAgeDrivers: 'Default',
tbxInsExpDrivers: 'Default',
cbxLastPaymentRedemption: 'Default',
cbxPriceWithDiscount: 'Default',
cbxFullPriceWithDiscount: 'Default',
cbxCostIncrease: 'Default', cbxCostIncrease: 'Default',
cbxInsurance: 'Default',
cbxRegistrationQuote: 'Default',
cbxTechnicalCardQuote: 'Default',
cbxNSIB: 'Default',
tbxQuoteName: 'Default',
radioQuoteContactGender: 'Default',
cbxQuoteRedemptionGraph: 'Default',
cbxShowFinGAP: 'Default',
cbxDisableChecks: 'Default', cbxDisableChecks: 'Default',
selectRegistration: 'Default', cbxFullPriceWithDiscount: 'Default',
selectInsNSIB: 'Default', cbxInsDecentral: 'Default',
selectTechnicalCard: 'Default', cbxInsUnlimitDrivers: 'Default',
selectRequirementTelematic: 'Default', cbxInsurance: 'Default',
selectTelematic: 'Default', cbxLastPaymentRedemption: 'Default',
selectTracker: 'Default', cbxLeaseObjectUsed: 'Default',
tbxMileage: 'Default', cbxNSIB: 'Default',
radioCalcType: 'Default', cbxPriceWithDiscount: 'Default',
tbxTotalPayments: 'Default', cbxQuoteRedemptionGraph: 'Default',
radioObjectRegistration: 'Default', cbxRecalcWithRevision: 'Default',
selectObjectRegionRegistration: 'Default', cbxRegistrationQuote: 'Default',
tbxVehicleTaxInYear: 'Default', cbxShowFinGAP: 'Default',
selectObjectCategoryTax: 'Default', cbxTechnicalCardQuote: 'Default',
radioTypePTS: 'Default', cbxWithTrailer: 'Default',
selectLegalClientRegion: 'Default', labelDepreciationGroup: 'Default',
selectLegalClientTown: 'Default',
selectSubsidy: 'Default',
tbxSubsidySum: 'Default',
selectFuelCard: 'Default',
tbxMinPriceChange: 'Default',
linkDownloadKp: 'Default',
selectImportProgram: 'Default',
tbxImportProgramSum: 'Default',
tbxAddEquipmentPrice: 'Default',
labelLeaseObjectRisk: 'Default',
tbxInsKaskoPriceLeasePeriod: 'Default',
labelIrrInfo: 'Default', labelIrrInfo: 'Default',
labelLeaseObjectRisk: 'Default',
labelRegistrationDescription: 'Default', labelRegistrationDescription: 'Default',
linkDownloadKp: 'Default',
linkLeadUrl: 'Default', linkLeadUrl: 'Default',
linkOpportunityUrl: 'Default', linkOpportunityUrl: 'Default',
linkQuoteUrl: 'Default', linkQuoteUrl: 'Default',
tbxBonusCoefficient: 'Default', radioBalanceHolder: 'Default',
btnCalculate: 'Default', radioCalcType: 'Default',
btnCreateKP: 'Default', radioDeliveryTime: 'Default',
radioGraphType: 'Default',
radioInfuranceOPF: 'Disabled',
radioInsKaskoType: 'Default',
radioLastPaymentRule: 'Default',
radioObjectRegistration: 'Default',
radioQuoteContactGender: 'Default',
radioTypePTS: 'Default',
selectBrand: 'Default',
selectCalcBroker: 'Default',
selectCalcBrokerRewardCondition: 'Default',
selectCalcDoubleAgent: 'Default',
selectCalcDoubleAgentRewardCondition: 'Default',
selectCalcFinDepartment: 'Default',
selectClientRisk: 'Default',
selectClientType: 'Disabled',
selectConfiguration: 'Default',
selectDealer: 'Default',
selectDealerBroker: 'Default',
selectDealerBrokerRewardCondition: 'Default',
selectDealerPerson: 'Default',
selectDealerRewardCondition: 'Default',
selectEngineType: 'Default',
selectFinDepartmentRewardCondtion: 'Default',
selectFuelCard: 'Default',
selectGPSBrand: 'Default',
selectGPSModel: 'Default',
selectHighSeasonStart: 'Default',
selectImportProgram: 'Default',
selectIndAgent: 'Default',
selectIndAgentRewardCondition: 'Default',
selectInsNSIB: 'Default',
selectLead: 'Default',
selectLeaseObjectCategory: 'Disabled',
selectLeaseObjectType: 'Default',
selectLeaseObjectUseFor: 'Default',
selectLeasingWithoutKasko: 'Default', selectLeasingWithoutKasko: 'Default',
selectLegalClientRegion: 'Default',
selectLegalClientTown: 'Default',
selectModel: 'Default',
selectObjectCategoryTax: 'Default',
selectObjectRegionRegistration: 'Default',
selectObjectTypeTax: 'Disabled',
selectOpportunity: 'Default',
selectProduct: 'Default',
selectQuote: 'Default',
selectRate: 'Disabled',
selectRegionRegistration: 'Default',
selectRegistration: 'Default',
selectRequirementTelematic: 'Default',
selectSeasonType: 'Default',
selectSubsidy: 'Default',
selectSupplierCurrency: 'Default',
selectTarif: 'Disabled',
selectTechnicalCard: 'Default',
selectTelematic: 'Default',
selectTownRegistration: 'Default',
selectTracker: 'Default',
tbxAddEquipmentPrice: 'Default',
tbxBonusCoefficient: 'Default',
tbxCalcBrokerRewardSum: 'Disabled',
tbxCalcDoubleAgentRewardSumm: 'Disabled',
tbxComissionPerc: 'Default',
tbxComissionRub: 'Default',
tbxCountSeats: 'Default',
tbxCreditRate: 'Disabled',
tbxDealerBrokerRewardSumm: 'Disabled',
tbxDealerRewardSumm: 'Disabled',
tbxEngineHours: 'Default',
tbxEngineVolume: 'Default',
tbxFinDepartmentRewardSumm: 'Disabled',
tbxFirstPaymentPerc: 'Default',
tbxFirstPaymentRub: 'Default',
tbxINNForCalc: 'Disabled',
tbxIRR_Perc: 'Default',
tbxImportProgramSum: 'Default',
tbxImporterRewardPerc: 'Disabled',
tbxImporterRewardRub: 'Disabled',
tbxIndAgentRewardSumm: 'Disabled',
tbxInsAgeDrivers: 'Default',
tbxInsExpDrivers: 'Default',
tbxInsFranchise: 'Default',
tbxInsKaskoPriceLeasePeriod: 'Default',
tbxLastPaymentPerc: 'Default',
tbxLastPaymentRub: 'Default',
tbxLeaseObjectCount: 'Default',
tbxLeaseObjectMotorPower: 'Default',
tbxLeaseObjectPrice: 'Default',
tbxLeaseObjectPriceWthtVAT: 'Disabled',
tbxLeaseObjectYear: 'Default',
tbxLeasingPeriod: 'Default',
tbxMaxMass: 'Default',
tbxMaxPriceChange: 'Disabled',
tbxMaxSpeed: 'Default',
tbxMileage: 'Default',
tbxMinPriceChange: 'Default',
tbxParmentsDecreasePercent: 'Default',
tbxQuoteName: 'Default',
tbxRedemptionPaymentSum: 'Disabled',
tbxSaleBonus: 'Default',
tbxSubsidySum: 'Default',
tbxSupplierDiscountPerc: 'Default',
tbxSupplierDiscountRub: 'Default',
tbxTotalPayments: 'Default',
tbxVATInLeaseObjectPrice: 'Default',
tbxVehicleTaxInLeasingPeriod: 'Disabled',
tbxVehicleTaxInYear: 'Default',
}; };
export default defaultStatuses; export default defaultStatuses;

View File

@ -1,143 +1,144 @@
import { RATE } from 'constants/values'; /* eslint-disable canonical/sort-keys */
import { RATE } from '@/constants/values';
import type { CalculationValues } from '@/stores/calculation/values/types';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import type { CalculationValues } from 'stores/calculation/values/types';
const defaultValues: CalculationValues = { const defaultValues: CalculationValues = {
lead: null, addEquipmentPrice: 0,
opportunity: null,
quote: null,
recalcWithRevision: false,
leaseObjectPrice: 1_000_000,
VATInLeaseObjectPrice: 0,
leaseObjectPriceWthtVAT: 0,
engineHours: 0,
supplierCurrency: null,
supplierDiscountRub: 0,
supplierDiscountPerc: 0,
leasingPeriod: 13,
firstPaymentPerc: 25,
firstPaymentRub: 0,
lastPaymentPerc: 1,
lastPaymentRule: 100_000_001,
redemptionPaymentSum: 1000,
balanceHolder: 100_000_001, balanceHolder: 100_000_001,
graphType: 100_000_000, bonusCoefficient: 1,
parmentsDecreasePercent: 94,
seasonType: null,
highSeasonStart: null,
comissionPerc: 0,
comissionRub: 0,
saleBonus: 1.3,
IRR_Perc: 20,
brand: null, brand: null,
model: null,
configuration: null,
deliveryTime: 100_000_000,
leaseObjectCount: 1,
withTrailer: false,
leaseObjectUsed: false,
maxMass: 0,
countSeats: 0,
maxSpeed: 0,
leaseObjectYear: dayjs().year(),
engineType: 100_000_000,
leaseObjectCategory: null,
leaseObjectMotorPower: 0,
engineVolume: 0,
dealerRewardSumm: 0,
dealerBrokerRewardSumm: 0,
indAgent: null,
calcDoubleAgent: null,
calcBroker: null, calcBroker: null,
calcFinDepartment: null, calcBrokerRewardCondition: null,
dealerPerson: null,
dealerBroker: null,
dealer: null,
indAgentRewardSumm: 0,
calcDoubleAgentRewardSumm: 0,
calcBrokerRewardSum: 0, calcBrokerRewardSum: 0,
finDepartmentRewardSumm: 0, calcDoubleAgent: null,
insKaskoType: 100_000_000, calcDoubleAgentRewardCondition: null,
insDecentral: false, calcDoubleAgentRewardSumm: 0,
insUnlimitDrivers: true, calcFinDepartment: null,
insAgeDrivers: 0,
insExpDrivers: 0,
lastPaymentRedemption: true,
priceWithDiscount: false,
fullPriceWithDiscount: false,
costIncrease: true,
insurance: true,
registrationQuote: true,
technicalCardQuote: true,
NSIB: true,
quoteContactGender: 100_000_000,
quoteRedemptionGraph: true,
showFinGAP: true,
creditRate: RATE,
requirementTelematic: 100_000_000,
maxPriceChange: 0,
importerRewardPerc: 0,
importerRewardRub: 0,
disableChecks: false,
insFranchise: 0,
rate: null,
calcType: 100_000_000, calcType: 100_000_000,
totalPayments: 0,
vehicleTaxInYear: 0,
vehicleTaxInLeasingPeriod: 0,
objectRegistration: 100_000_000,
typePTS: 100_000_001,
insNSIB: null,
regionRegistration: null,
legalClientRegion: null,
legalClientTown: null,
infuranceOPF: null,
product: null,
clientRisk: null, clientRisk: null,
clientType: null, clientType: null,
lastPaymentRub: 0, comissionPerc: 0,
leaseObjectType: null, comissionRub: 0,
leaseObjectUseFor: null, configuration: null,
dealerRewardCondition: null, costIncrease: true,
countSeats: 0,
creditRate: RATE,
dealer: null,
dealerBroker: null,
dealerBrokerRewardCondition: null, dealerBrokerRewardCondition: null,
indAgentRewardCondition: null, dealerBrokerRewardSumm: 0,
calcDoubleAgentRewardCondition: null, dealerPerson: null,
calcBrokerRewardCondition: null, dealerRewardCondition: null,
dealerRewardSumm: 0,
deliveryTime: 100_000_000,
depreciationGroup: '-',
disableChecks: false,
discountRub: 0,
engineHours: 0,
engineType: 100_000_000,
engineVolume: 0,
finDepartmentRewardCondtion: null, finDepartmentRewardCondtion: null,
finDepartmentRewardSumm: 0,
firstPaymentPerc: 25,
firstPaymentRub: 0,
fuelCard: null,
fullPriceWithDiscount: false,
GPSBrand: null, GPSBrand: null,
GPSModel: null, GPSModel: null,
townRegistration: null, graphType: 100_000_000,
INNForCalc: 0, highSeasonStart: null,
quoteName: null, importerRewardPerc: 0,
tarif: null, importerRewardRub: 0,
minPriceChange: 0,
registration: null,
technicalCard: null,
telematic: null,
tracker: null,
mileage: 0,
objectRegionRegistration: null,
objectCategoryTax: null,
objectTypeTax: null,
subsidy: null,
fuelCard: null,
kpUrl: null,
leadUrl: null,
opportunityUrl: null,
quoteUrl: null,
subsidySum: 0,
leaseObjectRiskName: '-',
insKaskoPriceLeasePeriod: 0,
irrInfo: '-',
registrationDescription: '-',
depreciationGroup: '-',
importProgram: null, importProgram: null,
importProgramSum: 0, importProgramSum: 0,
addEquipmentPrice: 0, indAgent: null,
bonusCoefficient: 1, indAgentRewardCondition: null,
plPriceRub: 0, indAgentRewardSumm: 0,
discountRub: 0, infuranceOPF: null,
INNForCalc: 0,
insAgeDrivers: 0,
insDecentral: false,
insExpDrivers: 0,
insFranchise: 0,
insKaskoPriceLeasePeriod: 0,
insKaskoType: 100_000_000,
insNSIB: null,
insUnlimitDrivers: true,
insurance: true,
IRR_Perc: 20,
irrInfo: '-',
kpUrl: null,
lastPaymentPerc: 1,
lastPaymentRedemption: true,
lastPaymentRub: 0,
lastPaymentRule: 100_000_001,
lead: null,
leadUrl: null,
leaseObjectCategory: null,
leaseObjectCount: 1,
leaseObjectMotorPower: 0,
leaseObjectPrice: 1_000_000,
leaseObjectPriceWthtVAT: 0,
leaseObjectRiskName: '-',
leaseObjectType: null,
leaseObjectUsed: false,
leaseObjectUseFor: null,
leaseObjectYear: dayjs().year(),
leasingPeriod: 13,
leasingWithoutKasko: null, leasingWithoutKasko: null,
legalClientRegion: null,
legalClientTown: null,
maxMass: 0,
maxPriceChange: 0,
maxSpeed: 0,
mileage: 0,
minPriceChange: 0,
model: null,
NSIB: true,
objectCategoryTax: null,
objectRegionRegistration: null,
objectRegistration: 100_000_000,
objectTypeTax: null,
opportunity: null,
opportunityUrl: null,
parmentsDecreasePercent: 94,
plPriceRub: 0,
priceWithDiscount: false,
product: null,
quote: null,
quoteContactGender: 100_000_000,
quoteName: null,
quoteRedemptionGraph: true,
quoteUrl: null,
rate: null,
recalcWithRevision: false,
redemptionPaymentSum: 1_000,
regionRegistration: null,
registration: null,
registrationDescription: '-',
registrationQuote: true,
requirementTelematic: 100_000_000,
saleBonus: 1.3,
seasonType: null,
showFinGAP: true,
subsidy: null,
subsidySum: 0,
supplierCurrency: null,
supplierDiscountPerc: 0,
supplierDiscountRub: 0,
tarif: null,
technicalCard: null,
technicalCardQuote: true,
telematic: null,
totalPayments: 0,
townRegistration: null,
tracker: null,
typePTS: 100_000_001,
VATInLeaseObjectPrice: 0,
vehicleTaxInLeasingPeriod: 0,
vehicleTaxInYear: 0,
withTrailer: false,
}; };
export default defaultValues; export default defaultValues;

View File

@ -1,5 +1,4 @@
/* eslint-disable import/prefer-default-export */ import getUrls from '@/config/urls';
import getUrls from 'config/urls';
const { BASE_PATH } = getUrls(); const { BASE_PATH } = getUrls();

View File

@ -1,17 +1,13 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const { z } = require('zod'); const { z } = require('zod');
const envSchema = z.object({ const envSchema = z.object({
USE_DEV_COLORS: z
.unknown()
.optional()
.transform((val) => !!val),
PORT: z.string().optional(),
BASE_PATH: z.string().optional().default(''), BASE_PATH: z.string().optional().default(''),
USERS_SUPER: z.string().optional().default(''), PORT: z.string().optional(),
URL_CORE_FINGAP_DIRECT: z.string(),
URL_CRM_GRAPHQL_DIRECT: z.string(), URL_CRM_GRAPHQL_DIRECT: z.string(),
URL_GET_USER_DIRECT: z.string(), URL_GET_USER_DIRECT: z.string(),
URL_CORE_FINGAP_DIRECT: z.string(), USE_DEV_COLORS: z.unknown().optional().transform(Boolean),
USERS_SUPER: z.string().optional().default(''),
}); });
module.exports = envSchema; module.exports = envSchema;

View File

@ -1,13 +1,14 @@
/* eslint-disable import/prefer-default-export */
import { z } from 'zod'; import { z } from 'zod';
export const RiskSchema = z.object({ export const RiskSchema = z
.object({
calcType: z.number(),
key: z.string(), key: z.string(),
keys: z.array(z.string()).optional(),
premium: z.number(),
premiumPerc: z.number(),
riskId: z.string(), riskId: z.string(),
riskName: z.string(), riskName: z.string(),
calcType: z.number(),
premiumPerc: z.number(),
sum: z.number(), sum: z.number(),
premium: z.number(), })
keys: z.array(z.string()).optional(), .strict();
});

View File

@ -1,12 +1,14 @@
import { z } from 'zod'; import { z } from 'zod';
export const KeysSchema = z.union([z.literal('osago'), z.literal('kasko'), z.literal('fingap')]); export const KeysSchema = z.enum(['osago', 'kasko', 'fingap']);
export const RowSchema = z.object({ export const RowSchema = z
key: KeysSchema, .object({
policyType: z.string(),
insuranceCompany: z.string().nullable(),
insured: z.number().nullable(),
insCost: z.number(), insCost: z.number(),
insTerm: z.number().nullable(), insTerm: z.number().nullable(),
}); insuranceCompany: z.string().nullable(),
insured: z.number().nullable(),
key: KeysSchema,
policyType: z.string(),
})
.strict();

View File

@ -1,7 +1,9 @@
import { z } from 'zod'; import { z } from 'zod';
const PaymentsSchema = z.object({ const PaymentsSchema = z
.object({
values: z.number().array(), values: z.number().array(),
}); })
.strict();
export default PaymentsSchema; export default PaymentsSchema;

View File

@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const envSchema = require('./env'); const envSchema = require('./env');
const publicRuntimeConfigSchema = envSchema.pick({ const publicRuntimeConfigSchema = envSchema.pick({
@ -8,11 +7,11 @@ const publicRuntimeConfigSchema = envSchema.pick({
}); });
const serverRuntimeConfigSchema = envSchema.pick({ const serverRuntimeConfigSchema = envSchema.pick({
PORT: true,
BASE_PATH: true, BASE_PATH: true,
PORT: true,
URL_CORE_FINGAP_DIRECT: true,
URL_CRM_GRAPHQL_DIRECT: true, URL_CRM_GRAPHQL_DIRECT: true,
URL_GET_USER_DIRECT: true, URL_GET_USER_DIRECT: true,
URL_CORE_FINGAP_DIRECT: true,
}); });
module.exports = { module.exports = {

View File

@ -1,145 +1,152 @@
/* eslint-disable canonical/sort-keys */
import { z } from 'zod'; import { z } from 'zod';
const ValuesSchema = z.object({ const ValuesSchema = z
lead: z.string().nullable(), .object({
opportunity: z.string().nullable(),
quote: z.string().nullable(),
recalcWithRevision: z.boolean(),
product: z.string().nullable(),
clientRisk: z.string().nullable(),
clientType: z.string().nullable(),
leaseObjectPrice: z.number(),
supplierCurrency: z.string().nullable(),
supplierDiscountRub: z.number(),
supplierDiscountPerc: z.number(),
leasingPeriod: z.number(),
firstPaymentPerc: z.number(),
firstPaymentRub: z.number(),
lastPaymentPerc: z.number(),
lastPaymentRub: z.number(),
lastPaymentRule: z.number().nullable(),
importProgram: z.string().nullable(),
importProgramSum: z.number(),
addEquipmentPrice: z.number(), addEquipmentPrice: z.number(),
redemptionPaymentSum: z.number(),
balanceHolder: z.number().nullable(), balanceHolder: z.number().nullable(),
graphType: z.number().nullable(), bonusCoefficient: z.number(),
parmentsDecreasePercent: z.number(),
seasonType: z.number().nullable(),
highSeasonStart: z.number().nullable(),
comissionPerc: z.number(),
comissionRub: z.number(),
saleBonus: z.number(),
IRR_Perc: z.number(),
leaseObjectType: z.string().nullable(),
deliveryTime: z.number().nullable(),
leaseObjectCount: z.number(),
withTrailer: z.boolean(),
leaseObjectUsed: z.boolean(),
maxMass: z.number(),
countSeats: z.number(),
maxSpeed: z.number(),
brand: z.string().nullable(), brand: z.string().nullable(),
model: z.string().nullable(),
configuration: z.string().nullable(),
leaseObjectYear: z.number(),
engineType: z.number().nullable(),
leaseObjectCategory: z.number().nullable(),
leaseObjectMotorPower: z.number(),
engineVolume: z.number(),
leaseObjectUseFor: z.number().nullable(),
dealer: z.string().nullable(),
dealerPerson: z.string().nullable(),
dealerRewardCondition: z.string().nullable(),
dealerRewardSumm: z.number(),
dealerBroker: z.string().nullable(),
dealerBrokerRewardCondition: z.string().nullable(),
dealerBrokerRewardSumm: z.number(),
indAgent: z.string().nullable(),
indAgentRewardCondition: z.string().nullable(),
indAgentRewardSumm: z.number(),
calcDoubleAgent: z.string().nullable(),
calcDoubleAgentRewardCondition: z.string().nullable(),
calcDoubleAgentRewardSumm: z.number(),
calcBroker: z.string().nullable(), calcBroker: z.string().nullable(),
calcBrokerRewardCondition: z.string().nullable(), calcBrokerRewardCondition: z.string().nullable(),
calcBrokerRewardSum: z.number(), calcBrokerRewardSum: z.number(),
calcDoubleAgent: z.string().nullable(),
calcDoubleAgentRewardCondition: z.string().nullable(),
calcDoubleAgentRewardSumm: z.number(),
calcFinDepartment: z.string().nullable(), calcFinDepartment: z.string().nullable(),
calcType: z.number().nullable(),
clientRisk: z.string().nullable(),
clientType: z.string().nullable(),
comissionPerc: z.number(),
comissionRub: z.number(),
configuration: z.string().nullable(),
costIncrease: z.boolean(),
countSeats: z.number(),
creditRate: z.number(),
dealer: z.string().nullable(),
dealerBroker: z.string().nullable(),
dealerBrokerRewardCondition: z.string().nullable(),
dealerBrokerRewardSumm: z.number(),
dealerPerson: z.string().nullable(),
dealerRewardCondition: z.string().nullable(),
dealerRewardSumm: z.number(),
deliveryTime: z.number().nullable(),
disableChecks: z.boolean(),
engineHours: z.number(),
engineType: z.number().nullable(),
engineVolume: z.number(),
finDepartmentRewardCondtion: z.string().nullable(), finDepartmentRewardCondtion: z.string().nullable(),
finDepartmentRewardSumm: z.number(), finDepartmentRewardSumm: z.number(),
firstPaymentPerc: z.number(),
firstPaymentRub: z.number(),
fuelCard: z.string().nullable(),
fullPriceWithDiscount: z.boolean(),
GPSBrand: z.string().nullable(), GPSBrand: z.string().nullable(),
GPSModel: z.string().nullable(), GPSModel: z.string().nullable(),
regionRegistration: z.string().nullable(), graphType: z.number().nullable(),
townRegistration: z.string().nullable(), highSeasonStart: z.number().nullable(),
infuranceOPF: z.number().nullable(),
insKaskoType: z.number().nullable(),
insDecentral: z.boolean(),
insFranchise: z.number(),
insUnlimitDrivers: z.boolean(),
insAgeDrivers: z.number(),
insExpDrivers: z.number(),
INNForCalc: z.number(),
lastPaymentRedemption: z.boolean(),
priceWithDiscount: z.boolean(),
fullPriceWithDiscount: z.boolean(),
costIncrease: z.boolean(),
insurance: z.boolean(),
registrationQuote: z.boolean(),
technicalCardQuote: z.boolean(),
NSIB: z.boolean(),
quoteName: z.string().nullable(),
quoteContactGender: z.number().nullable(),
quoteRedemptionGraph: z.boolean(),
showFinGAP: z.boolean(),
tarif: z.string().nullable(),
creditRate: z.number(),
rate: z.string().nullable(),
requirementTelematic: z.number().nullable(),
minPriceChange: z.number(),
maxPriceChange: z.number(),
importerRewardPerc: z.number(), importerRewardPerc: z.number(),
importerRewardRub: z.number(), importerRewardRub: z.number(),
disableChecks: z.boolean(), importProgram: z.string().nullable(),
registration: z.string().nullable(), importProgramSum: z.number(),
indAgent: z.string().nullable(),
indAgentRewardCondition: z.string().nullable(),
indAgentRewardSumm: z.number(),
infuranceOPF: z.number().nullable(),
INNForCalc: z.number(),
insAgeDrivers: z.number(),
insDecentral: z.boolean(),
insExpDrivers: z.number(),
insFranchise: z.number(),
insKaskoType: z.number().nullable(),
insNSIB: z.string().nullable(), insNSIB: z.string().nullable(),
technicalCard: z.string().nullable(), insUnlimitDrivers: z.boolean(),
telematic: z.string().nullable(), insurance: z.boolean(),
tracker: z.string().nullable(), IRR_Perc: z.number(),
mileage: z.number(), lastPaymentPerc: z.number(),
calcType: z.number().nullable(), lastPaymentRedemption: z.boolean(),
totalPayments: z.number(), lastPaymentRub: z.number(),
objectRegistration: z.number().nullable(), lastPaymentRule: z.number().nullable(),
objectRegionRegistration: z.string().nullable(), lead: z.string().nullable(),
vehicleTaxInYear: z.number(), leaseObjectCategory: z.number().nullable(),
vehicleTaxInLeasingPeriod: z.number(), leaseObjectCount: z.number(),
objectCategoryTax: z.number().nullable(), leaseObjectMotorPower: z.number(),
objectTypeTax: z.number().nullable(), leaseObjectPrice: z.number(),
typePTS: z.number().nullable(), leaseObjectPriceWthtVAT: z.number(),
leaseObjectType: z.string().nullable(),
leaseObjectUsed: z.boolean(),
leaseObjectUseFor: z.number().nullable(),
leaseObjectYear: z.number(),
leasingPeriod: z.number(),
leasingWithoutKasko: z.string().nullable(),
legalClientRegion: z.string().nullable(), legalClientRegion: z.string().nullable(),
legalClientTown: z.string().nullable(), legalClientTown: z.string().nullable(),
maxMass: z.number(),
maxPriceChange: z.number(),
maxSpeed: z.number(),
mileage: z.number(),
minPriceChange: z.number(),
model: z.string().nullable(),
NSIB: z.boolean(),
objectCategoryTax: z.number().nullable(),
objectRegionRegistration: z.string().nullable(),
objectRegistration: z.number().nullable(),
objectTypeTax: z.number().nullable(),
opportunity: z.string().nullable(),
parmentsDecreasePercent: z.number(),
priceWithDiscount: z.boolean(),
product: z.string().nullable(),
quote: z.string().nullable(),
quoteContactGender: z.number().nullable(),
quoteName: z.string().nullable(),
quoteRedemptionGraph: z.boolean(),
rate: z.string().nullable(),
recalcWithRevision: z.boolean(),
redemptionPaymentSum: z.number(),
regionRegistration: z.string().nullable(),
registration: z.string().nullable(),
registrationQuote: z.boolean(),
requirementTelematic: z.number().nullable(),
saleBonus: z.number(),
seasonType: z.number().nullable(),
showFinGAP: z.boolean(),
subsidy: z.string().nullable(), subsidy: z.string().nullable(),
fuelCard: z.string().nullable(), supplierCurrency: z.string().nullable(),
leaseObjectPriceWthtVAT: z.number(), supplierDiscountPerc: z.number(),
supplierDiscountRub: z.number(),
tarif: z.string().nullable(),
technicalCard: z.string().nullable(),
technicalCardQuote: z.boolean(),
telematic: z.string().nullable(),
totalPayments: z.number(),
townRegistration: z.string().nullable(),
tracker: z.string().nullable(),
typePTS: z.number().nullable(),
VATInLeaseObjectPrice: z.number(), VATInLeaseObjectPrice: z.number(),
engineHours: z.number(), vehicleTaxInLeasingPeriod: z.number(),
bonusCoefficient: z.number(), vehicleTaxInYear: z.number(),
leasingWithoutKasko: z.string().nullable(), withTrailer: z.boolean(),
/** Link Values */ /**
* Link Values
*/
kpUrl: z.string().nullable(), kpUrl: z.string().nullable(),
leadUrl: z.string().nullable(), leadUrl: z.string().nullable(),
opportunityUrl: z.string().nullable(), opportunityUrl: z.string().nullable(),
quoteUrl: z.string().nullable(), quoteUrl: z.string().nullable(),
/** Readonly Values */ /**
leaseObjectRiskName: z.string().nullable(), * Readonly Values
*/
depreciationGroup: z.string().nullable(),
discountRub: z.number(),
insKaskoPriceLeasePeriod: z.number(), insKaskoPriceLeasePeriod: z.number(),
irrInfo: z.string().nullable(), irrInfo: z.string().nullable(),
registrationDescription: z.string().nullable(), leaseObjectRiskName: z.string().nullable(),
depreciationGroup: z.string().nullable(),
subsidySum: z.number(),
plPriceRub: z.number(), plPriceRub: z.number(),
discountRub: z.number(), registrationDescription: z.string().nullable(),
}); subsidySum: z.number(),
})
.strict();
export default ValuesSchema; export default ValuesSchema;

View File

@ -1,82 +1,36 @@
/* eslint-disable object-curly-newline */ /* eslint-disable canonical/sort-keys */
import type * as Insurance from 'Components/Calculation/Form/Insurance/InsuranceTable/types'; import type * as Insurance from '@/Components/Calculation/Form/Insurance/InsuranceTable/types';
const defaultRowOptions: Insurance.RowOptions = {
insured: [
{
label: 'ЛП',
value: 100_000_000,
},
{
label: 'ЛД',
value: 100_000_001,
},
],
insTerm: [
{
label: '12 месяцев',
value: 100_000_000,
},
{
label: 'Срок ДЛ',
value: 100_000_001,
},
],
insCost: [],
insuranceCompany: [],
policyType: [],
};
export const defaultOptions: Record<Insurance.Keys, Insurance.RowOptions> = { export const defaultOptions: Record<Insurance.Keys, Insurance.RowOptions> = {
osago: { osago: defaultRowOptions,
insured: [ kasko: defaultRowOptions,
{ fingap: defaultRowOptions,
label: 'ЛП',
value: 100_000_000,
},
{
label: 'ЛД',
value: 100_000_001,
},
],
insTerm: [
{
label: '12 месяцев',
value: 100_000_000,
},
{
label: 'Срок ДЛ',
value: 100_000_001,
},
],
insCost: [],
insuranceCompany: [],
policyType: [],
},
kasko: {
insured: [
{
label: 'ЛП',
value: 100_000_000,
},
{
label: 'ЛД',
value: 100_000_001,
},
],
insTerm: [
{
label: '12 месяцев',
value: 100_000_000,
},
{
label: 'Срок ДЛ',
value: 100_000_001,
},
],
insCost: [],
insuranceCompany: [],
policyType: [],
},
fingap: {
insured: [
{
label: 'ЛП',
value: 100_000_000,
},
{
label: 'ЛД',
value: 100_000_001,
},
],
insTerm: [
{
label: '12 месяцев',
value: 100_000_000,
},
{
label: 'Срок ДЛ',
value: 100_000_001,
},
],
insCost: [],
insuranceCompany: [],
policyType: [],
},
}; };
export const defaultValues: Insurance.RowValues[] = [ export const defaultValues: Insurance.RowValues[] = [
@ -108,24 +62,24 @@ export const defaultValues: Insurance.RowValues[] = [
export const defaultStatuses: Record<Insurance.Keys, Insurance.RowStatuses> = { export const defaultStatuses: Record<Insurance.Keys, Insurance.RowStatuses> = {
osago: { osago: {
insTerm: 'Disabled', policyType: 'Default',
insCost: 'Default',
insuranceCompany: 'Default', insuranceCompany: 'Default',
insured: 'Default', insured: 'Default',
policyType: 'Default', insCost: 'Default',
insTerm: 'Disabled',
}, },
kasko: { kasko: {
insTerm: 'Disabled', policyType: 'Default',
insCost: 'Default',
insuranceCompany: 'Default', insuranceCompany: 'Default',
insured: 'Default', insured: 'Default',
policyType: 'Default', insCost: 'Default',
insTerm: 'Disabled',
}, },
fingap: { fingap: {
insCost: 'Disabled', policyType: 'Default',
insuranceCompany: 'Default', insuranceCompany: 'Default',
insured: 'Default', insured: 'Default',
insCost: 'Disabled',
insTerm: 'Default', insTerm: 'Default',
policyType: 'Default',
}, },
}; };

View File

@ -1,3 +1,4 @@
/* eslint-disable canonical/sort-keys */
const threshold = 0; const threshold = 0;
const screens = { const screens = {

View File

@ -1,35 +1,35 @@
import urls from 'constants/urls'; import { publicRuntimeConfigSchema, serverRuntimeConfigSchema } from './schema/runtime-config';
import urls from '@/constants/urls';
import getConfig from 'next/config'; import getConfig from 'next/config';
import { isServer } from 'tools/common'; import { isServer } from 'tools/common';
import { publicRuntimeConfigSchema, serverRuntimeConfigSchema } from './schema/runtime-config';
const { serverRuntimeConfig, publicRuntimeConfig } = getConfig(); const { serverRuntimeConfig, publicRuntimeConfig } = getConfig();
function getUrls() { function getUrls() {
const { BASE_PATH } = publicRuntimeConfigSchema.parse(publicRuntimeConfig);
if (isServer()) { if (isServer()) {
const { URL_CRM_GRAPHQL_DIRECT, URL_GET_USER_DIRECT, URL_CORE_FINGAP_DIRECT, BASE_PATH, PORT } = const { URL_CRM_GRAPHQL_DIRECT, URL_GET_USER_DIRECT, URL_CORE_FINGAP_DIRECT, PORT } =
serverRuntimeConfigSchema.parse(serverRuntimeConfig); serverRuntimeConfigSchema.parse(serverRuntimeConfig);
return { return {
PORT,
BASE_PATH, BASE_PATH,
PORT,
URL_CORE_FINGAP: URL_CORE_FINGAP_DIRECT,
URL_CRM_GRAPHQL: URL_CRM_GRAPHQL_DIRECT, URL_CRM_GRAPHQL: URL_CRM_GRAPHQL_DIRECT,
URL_GET_USER: URL_GET_USER_DIRECT, URL_GET_USER: URL_GET_USER_DIRECT,
URL_CORE_FINGAP: URL_CORE_FINGAP_DIRECT,
}; };
} }
const { BASE_PATH } = publicRuntimeConfigSchema.parse(publicRuntimeConfig);
function withBasePath(url: string) { function withBasePath(url: string) {
return BASE_PATH + url; return BASE_PATH + url;
} }
return { return {
BASE_PATH, BASE_PATH,
URL_CORE_FINGAP: withBasePath(urls.URL_CORE_FINGAP_PROXY),
URL_CRM_GRAPHQL: withBasePath(urls.URL_CRM_GRAPHQL_PROXY), URL_CRM_GRAPHQL: withBasePath(urls.URL_CRM_GRAPHQL_PROXY),
URL_GET_USER: withBasePath(urls.URL_GET_USER_PROXY), URL_GET_USER: withBasePath(urls.URL_GET_USER_PROXY),
URL_CORE_FINGAP: withBasePath(urls.URL_CORE_FINGAP_PROXY),
}; };
} }

View File

@ -10,6 +10,6 @@ const COLORS_DEV = {
}; };
module.exports = { module.exports = {
COLORS_PROD,
COLORS_DEV, COLORS_DEV,
COLORS_PROD,
}; };

View File

@ -1,2 +1 @@
/* eslint-disable import/prefer-default-export */
export const STALE_TIME = Number.POSITIVE_INFINITY; export const STALE_TIME = Number.POSITIVE_INFINITY;

View File

@ -1,5 +1,5 @@
module.exports = { module.exports = {
URL_GET_USER_PROXY: '/api/auth/user',
URL_CRM_GRAPHQL_PROXY: '/api/graphql/crm',
URL_CORE_FINGAP_PROXY: '/api/core/fingap', URL_CORE_FINGAP_PROXY: '/api/core/fingap',
URL_CRM_GRAPHQL_PROXY: '/api/graphql/crm',
URL_GET_USER_PROXY: '/api/auth/user',
}; };

View File

@ -16,6 +16,7 @@ const customJestConfig = {
moduleDirectories: ['node_modules', '<rootDir>/'], moduleDirectories: ['node_modules', '<rootDir>/'],
moduleNameMapper: { moduleNameMapper: {
// Handle module aliases (this will be automatically configured for you soon) // Handle module aliases (this will be automatically configured for you soon)
'^@/(.*)$': '<rootDir>/$1',
}, },
testEnvironment: 'jest-environment-jsdom', testEnvironment: 'jest-environment-jsdom',
preset: 'ts-jest', preset: 'ts-jest',

View File

@ -1,4 +1,4 @@
import getUrls from 'config/urls'; import getUrls from '@/config/urls';
import { rest } from 'msw'; import { rest } from 'msw';
const _ = require('radash'); const _ = require('radash');

View File

@ -15,49 +15,49 @@ const favicons = fs.readdirSync('./public/favicon/prod');
const faviconSubPath = env.USE_DEV_COLORS ? '/favicon/dev' : '/favicon/prod'; const faviconSubPath = env.USE_DEV_COLORS ? '/favicon/dev' : '/favicon/prod';
function buildFaviconRewrite(source) { function buildFaviconRewrite(source) {
return { return {
source,
destination: String.prototype.concat(env.BASE_PATH, faviconSubPath, source), destination: String.prototype.concat(env.BASE_PATH, faviconSubPath, source),
source,
}; };
} }
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */
const nextConfig = { const nextConfig = {
basePath: env.BASE_PATH, basePath: env.BASE_PATH,
transpilePackages: ['ui', 'tools'], compiler: {
output: 'standalone', styledComponents: true,
swcMinify: true, },
reactStrictMode: true,
eslint: { eslint: {
ignoreDuringBuilds: true, ignoreDuringBuilds: true,
}, },
compiler: { experimental: {
styledComponents: true, outputFileTracingRoot: path.join(__dirname, '../../'),
}, },
images: { images: {
deviceSizes: devices, deviceSizes: devices,
}, },
output: 'standalone',
publicRuntimeConfig: publicRuntimeConfigSchema.parse(env),
reactStrictMode: true,
async rewrites() { async rewrites() {
return [ return [
{ {
source: urls.URL_CRM_GRAPHQL_PROXY,
destination: env.URL_CRM_GRAPHQL_DIRECT, destination: env.URL_CRM_GRAPHQL_DIRECT,
source: urls.URL_CRM_GRAPHQL_PROXY,
}, },
{ {
source: urls.URL_GET_USER_PROXY,
destination: env.URL_GET_USER_DIRECT, destination: env.URL_GET_USER_DIRECT,
source: urls.URL_GET_USER_PROXY,
}, },
{ {
source: urls.URL_CORE_FINGAP_PROXY,
destination: env.URL_CORE_FINGAP_DIRECT, destination: env.URL_CORE_FINGAP_DIRECT,
source: urls.URL_CORE_FINGAP_PROXY,
}, },
...favicons.map((fileName) => buildFaviconRewrite(`/${fileName}`)), ...favicons.map((fileName) => buildFaviconRewrite(`/${fileName}`)),
]; ];
}, },
publicRuntimeConfig: publicRuntimeConfigSchema.parse(env),
serverRuntimeConfig: serverRuntimeConfigSchema.parse(env), serverRuntimeConfig: serverRuntimeConfigSchema.parse(env),
experimental: { swcMinify: true,
outputFileTracingRoot: path.join(__dirname, '../../'), transpilePackages: ['ui', 'tools'],
},
}; };
const plugins = [withLess]; const plugins = [withLess];

View File

@ -1,22 +1,20 @@
/* eslint-disable global-require */
import { ApolloProvider } from '@apollo/client';
import { QueryClientProvider } from '@tanstack/react-query';
import Layout from 'Components/Layout';
import { theme } from 'config/ui';
import Head from 'next/head';
import 'normalize.css'; import 'normalize.css';
import { useMemo } from 'react';
import StoreProvider from 'stores/Provider';
import { ThemeProvider } from 'styled-components';
import { GlobalStyle } from 'styles/global-style';
import { trpcClient } from 'trpc/client';
import AntdConfig from 'ui/elements/Config';
import 'ui/elements/styles/antd.less'; import 'ui/elements/styles/antd.less';
import '../styles/fonts.css'; import '../styles/fonts.css';
import '../styles/globals.css'; import '../styles/globals.css';
import initializeQueryClient from '@/api/client';
import initializeQueryClient from 'api/client'; import initializeApollo from '@/apollo/client';
import initializeApollo from 'apollo/client'; import Layout from '@/Components/Layout';
import { theme } from '@/config/ui';
import StoreProvider from '@/stores/Provider';
import { GlobalStyle } from '@/styles/global-style';
import { trpcClient } from '@/trpc/client';
import { ApolloProvider } from '@apollo/client';
import { QueryClientProvider } from '@tanstack/react-query';
import Head from 'next/head';
import { useMemo } from 'react';
import { ThemeProvider } from 'styled-components';
import AntdConfig from 'ui/elements/Config';
// eslint-disable-next-line turbo/no-undeclared-env-vars // eslint-disable-next-line turbo/no-undeclared-env-vars
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development') {

View File

@ -1,4 +1,5 @@
import { metaFavicon } from 'config/meta'; /* eslint-disable @typescript-eslint/explicit-member-accessibility */
import { metaFavicon } from '@/config/meta';
import Document, { Head, Html, Main, NextScript } from 'next/document'; import Document, { Head, Html, Main, NextScript } from 'next/document';
import { ServerStyleSheet } from 'styled-components'; import { ServerStyleSheet } from 'styled-components';
@ -8,8 +9,8 @@ export default class MyDocument extends Document {
const originalRenderPage = ctx.renderPage; const originalRenderPage = ctx.renderPage;
try { try {
// prettier-ignore ctx.renderPage = () =>
ctx.renderPage = () => originalRenderPage({ originalRenderPage({
enhanceApp: (App) => (props) => sheet.collectStyles(<App {...props} />), enhanceApp: (App) => (props) => sheet.collectStyles(<App {...props} />),
}); });

View File

@ -1,8 +1,8 @@
/* eslint-disable canonical/filename-match-regex */
import appRouter from '@/trpc/routers';
import * as trpcNext from '@trpc/server/adapters/next'; import * as trpcNext from '@trpc/server/adapters/next';
import appRouter from 'trpc/routers';
export default trpcNext.createNextApiHandler({ export default trpcNext.createNextApiHandler({
router: appRouter,
// eslint-disable-next-line object-curly-newline
createContext: () => ({}), createContext: () => ({}),
router: appRouter,
}); });

View File

@ -1,14 +1,14 @@
import { getUser } from '@/api/user/query';
import initializeApollo from '@/apollo/client';
import * as Calculation from '@/Components/Calculation';
import { CRMError } from '@/Components/Common/Error';
import Output from '@/Components/Output';
import { getOwnerData, useInsuranceData, useMainData } from '@/process/init/get-data';
import { useReactions } from '@/process/init/inject-reactions/hooks';
import { min } from '@/styles/mq';
import { dehydrate, QueryClient } from '@tanstack/react-query'; import { dehydrate, QueryClient } from '@tanstack/react-query';
import { getUser } from 'api/user/query';
import initializeApollo from 'apollo/client';
import * as Calculation from 'Components/Calculation';
import { CRMError } from 'Components/Common/Error';
import Output from 'Components/Output';
import Head from 'next/head'; import Head from 'next/head';
import { getOwnerData, useInsuranceData, useMainData } from 'process/init/get-data';
import { useReactions } from 'process/init/inject-reactions/hooks';
import styled from 'styled-components'; import styled from 'styled-components';
import { min } from 'styles/mq';
import { Box } from 'ui/grid'; import { Box } from 'ui/grid';
const Grid = styled(Box)` const Grid = styled(Box)`
@ -56,8 +56,8 @@ function Home({ error }) {
/** @type {import('next').GetServerSideProps} */ /** @type {import('next').GetServerSideProps} */
export const getServerSideProps = async ({ req }) => { export const getServerSideProps = async ({ req }) => {
const { cookie = '' } = req.headers; const { cookie = '' } = req.headers;
// prettier-ignore const queryGetUser = () =>
const queryGetUser = () => getUser({ getUser({
headers: { headers: {
cookie, cookie,
}, },

View File

@ -1,2 +1 @@
/* eslint-disable import/prefer-default-export */
export { default as validation } from './validation'; export { default as validation } from './validation';

View File

@ -1,11 +1,11 @@
import types from 'Components/Calculation/config/elements-types'; import types from '@/Components/Calculation/config/elements-types';
import type * as Values from 'Components/Calculation/config/map/values'; import type * as Values from '@/Components/Calculation/config/map/values';
import type * as Insurance from 'Components/Calculation/Form/Insurance/InsuranceTable/types'; import type * as Insurance from '@/Components/Calculation/Form/Insurance/InsuranceTable/types';
import type { ReactionsContext } from '@/process/types';
import { reaction } from 'mobx'; import { reaction } from 'mobx';
import type { ReactionsContext } from 'process/types';
import type { BaseOption } from 'ui/elements/types'; import type { BaseOption } from 'ui/elements/types';
function hasInvalidValueOrOptions(value: unknown, options: BaseOption<unknown>[]) { function hasInvalidValueOrOptions(value: unknown, options: Array<BaseOption<unknown>>) {
if (value === null) { if (value === null) {
return false; return false;
} }
@ -58,8 +58,8 @@ export default function validationReactions({ store }: ReactionsContext) {
const value = element.getValue(); const value = element.getValue();
return { return {
value,
options, options,
value,
}; };
}, },
({ value, options }) => { ({ value, options }) => {
@ -101,8 +101,8 @@ export default function validationReactions({ store }: ReactionsContext) {
const value = row.getValue('insuranceCompany'); const value = row.getValue('insuranceCompany');
return { return {
value,
options, options,
value,
}; };
}, },
({ value, options }) => { ({ value, options }) => {

View File

@ -1,8 +1,7 @@
/* eslint-disable @typescript-eslint/naming-convention */
import { gql } from '@apollo/client';
import initializeApollo from 'apollo/client';
import type * as CRMTypes from 'graphql/crm.types';
import type { GetQuoteDataInput, GetQuoteDataOutput } from '../load-kp/types'; import type { GetQuoteDataInput, GetQuoteDataOutput } from '../load-kp/types';
import initializeApollo from '@/apollo/client';
import type * as CRMTypes from '@/graphql/crm.types';
import { gql } from '@apollo/client';
const QUERY_GET_CONFIGURATOR_DATA_FROM_QUOTE = gql` const QUERY_GET_CONFIGURATOR_DATA_FROM_QUOTE = gql`
query GetConfiguratorDataFromQuote($quoteId: Uuid!) { query GetConfiguratorDataFromQuote($quoteId: Uuid!) {

View File

@ -1,11 +1,11 @@
/* eslint-disable @typescript-eslint/naming-convention */ /* eslint-disable @typescript-eslint/naming-convention */
import { radioGraphType, selectSeasonType } from 'config/default-options'; import { radioGraphType, selectSeasonType } from '@/config/default-options';
import * as CRMTypes from '@/graphql/crm.types';
import { SEASON_TYPES } from '@/process/payments/lib/seasons-constants';
import type { ReactionsContext } from '@/process/types';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc'; import utc from 'dayjs/plugin/utc';
import * as CRMTypes from 'graphql/crm.types';
import { reaction } from 'mobx'; import { reaction } from 'mobx';
import { SEASON_TYPES } from 'process/payments/lib/seasons-constants';
import type { ReactionsContext } from 'process/types';
import { diff } from 'radash'; import { diff } from 'radash';
import { normalizeOptions } from 'tools'; import { normalizeOptions } from 'tools';
@ -19,34 +19,35 @@ export default function commonReactions({ store, apolloClient }: ReactionsContex
const { product, subsidy, importProgram, dealer } = $calculation.$values.values; const { product, subsidy, importProgram, dealer } = $calculation.$values.values;
return { return {
dealerId: dealer,
importProgramId: importProgram,
productId: product, productId: product,
subsidyId: subsidy, subsidyId: subsidy,
importProgramId: importProgram,
dealerId: dealer,
}; };
}, },
// eslint-disable-next-line sonarjs/cognitive-complexity
async ({ productId, subsidyId, importProgramId, dealerId }) => { async ({ productId, subsidyId, importProgramId, dealerId }) => {
/** /**
#1 * #1
* DYN-190 При выборе значения в поле selectSubsidy необходимо добавить * DYN-190 При выборе значения в поле selectSubsidy необходимо добавить
* фильтрацию в полях при условии что selectSubsidy не равно null: * фильтрацию в полях при условии что selectSubsidy не равно null:
*
Тип предмета лизинга selectLeaseObjectType * Тип предмета лизинга selectLeaseObjectType
если с записью Субсидия нет связанных Типов предмета лизинга, * если с записью Субсидия нет связанных Типов предмета лизинга,
то указываются все записи согласно текущей фильтрации, * то указываются все записи согласно текущей фильтрации,
иначе указываются те записи, которые связаны с Субсидией, указанной в поле selectSubsidy * иначе указываются те записи, которые связаны с Субсидией, указанной в поле selectSubsidy
*
#2 * #2
* На изменение поля Продукт selectProduct добавляем фильтрацию списков: * На изменение поля Продукт selectProduct добавляем фильтрацию списков:
в поле Тип предмета лизинга selectLeaseObjectType - указываются те, которые связаны с продуктом. * в поле Тип предмета лизинга selectLeaseObjectType - указываются те, которые связаны с продуктом.
Если с Продуктом нет связанных Типов предмета лизинга, * Если с Продуктом нет связанных Типов предмета лизинга,
то указывается весь список. Это надо добавить в текущие условия фильтрации данного поля * то указывается весь список. Это надо добавить в текущие условия фильтрации данного поля
*
#3 * #3
Тип предмета лизинга selectLeaseObjectType * Тип предмета лизинга selectLeaseObjectType
если с записью Субсидия нет связанных Типов предмета лизинга, * если с записью Субсидия нет связанных Типов предмета лизинга,
то указываются все записи согласно текущей фильтрации, * то указываются все записи согласно текущей фильтрации,
иначе указываются те записи, которые связаны с Субсидией, указанной в поле selectImportProgram * иначе указываются те записи, которые связаны с Субсидией, указанной в поле selectImportProgram
*/ */
let { let {
@ -192,9 +193,9 @@ export default function commonReactions({ store, apolloClient }: ReactionsContex
/** /**
* На изменение поля Тариф selectTarif добавляем фильрацию в полях: * На изменение поля Тариф selectTarif добавляем фильрацию в полях:
в поле Вид графика radioGraphType должны закрываться значения для выбора, * в поле Вид графика radioGraphType должны закрываться значения для выбора,
которые указаны в массиве поля "Недопустимые виды графиков" evo_graphtype_exception. * которые указаны в массиве поля "Недопустимые виды графиков" evo_graphtype_exception.
Если в массиве пусто, значит допустимы все значения * Если в массиве пусто, значит допустимы все значения
*/ */
reaction( reaction(
() => $calculation.element('selectTarif').getValue(), () => $calculation.element('selectTarif').getValue(),
@ -231,8 +232,8 @@ export default function commonReactions({ store, apolloClient }: ReactionsContex
*/ */
reaction( reaction(
() => ({ () => ({
tarif: $calculation.element('selectTarif').getValue(),
graphType: $calculation.element('radioGraphType').getValue(), graphType: $calculation.element('radioGraphType').getValue(),
tarif: $calculation.element('selectTarif').getValue(),
}), }),
async ({ tarif, graphType }) => { async ({ tarif, graphType }) => {
let evo_tarif: CRMTypes.GetTarifQuery['evo_tarif'] = null; let evo_tarif: CRMTypes.GetTarifQuery['evo_tarif'] = null;
@ -249,7 +250,7 @@ export default function commonReactions({ store, apolloClient }: ReactionsContex
} }
const seasonTypesExeption = evo_tarif?.evo_seasons_type_exception || []; const seasonTypesExeption = evo_tarif?.evo_seasons_type_exception || [];
let seasonTypes: Array<number> = []; let seasonTypes: number[] = [];
if (graphType === 100_000_001 || graphType === 100_000_003) { if (graphType === 100_000_001 || graphType === 100_000_003) {
seasonTypes = SEASON_TYPES[graphType]; seasonTypes = SEASON_TYPES[graphType];
@ -300,13 +301,12 @@ export default function commonReactions({ store, apolloClient }: ReactionsContex
} }
); );
/* eslint-disable max-len */
/** /**
* Добавить фильтр для поля selectProduct (работает на загрузку КП) * Добавить фильтр для поля selectProduct (работает на загрузку КП)
* если recalcWithRevision=True, то в списке поля selectProduct должны отображаться * если recalcWithRevision=True, то в списке поля selectProduct должны отображаться
* записи quote.evo_baseproductid из поля Предложение selectQuote + дать возможность выбирать продукт, * записи quote.evo_baseproductid из поля Предложение selectQuote + дать возможность выбирать продукт,
* связанный с оquote.evo_baseproductid из поля Предложение selectQuote по связи evo_evo_baseproduct_evo_baseproduct * связанный с оquote.evo_baseproductid из поля Предложение selectQuote по связи evo_evo_baseproduct_evo_baseproduct
/* eslint-enable */ */
reaction( reaction(
() => $calculation.element('selectQuote').getValue(), () => $calculation.element('selectQuote').getValue(),
async (quoteId) => { async (quoteId) => {
@ -315,11 +315,11 @@ export default function commonReactions({ store, apolloClient }: ReactionsContex
const { const {
data: { evo_baseproducts }, data: { evo_baseproducts },
} = await apolloClient.query({ } = await apolloClient.query({
fetchPolicy: 'network-only',
query: CRMTypes.GetProductsDocument, query: CRMTypes.GetProductsDocument,
variables: { variables: {
currentDate, currentDate,
}, },
fetchPolicy: 'network-only',
}); });
if (!$calculation.element('cbxRecalcWithRevision').getValue()) { if (!$calculation.element('cbxRecalcWithRevision').getValue()) {

View File

@ -1,26 +1,24 @@
import * as CRMTypes from 'graphql/crm.types'; /* eslint-disable @typescript-eslint/naming-convention */
import * as CRMTypes from '@/graphql/crm.types';
import type { ReactionsContext } from '@/process/types';
import { reaction } from 'mobx'; import { reaction } from 'mobx';
import type { ReactionsContext } from 'process/types';
export default function validationReactions({ store, apolloClient }: ReactionsContext) { export default function validationReactions({ store, apolloClient }: ReactionsContext) {
const { $calculation } = store; const { $calculation } = store;
/* eslint-disable max-len */
/** /**
* На изменение поля Процет убывания платежей tbxParmentsDecreasePercent необходимо заложить проверку: * На изменение поля Процет убывания платежей tbxParmentsDecreasePercent необходимо заложить проверку:
* Если значение поля меньше значения в поле "Минимальный % убывания платежей" evo_min_decreasing_perc из записи, * Если значение поля меньше значения в поле "Минимальный % убывания платежей" evo_min_decreasing_perc из записи,
* указанной в поле ТарифselectTarif , то поле Процет убывания платежей tbxParmentsDecreasePercent должно обводиться красной рамкой * указанной в поле ТарифselectTarif , то поле Процет убывания платежей tbxParmentsDecreasePercent должно обводиться красной рамкой
* и выводиться сообщение "Процент убывания не может быть меньше минимального значения по данному тарифу * и выводиться сообщение "Процент убывания не может быть меньше минимального значения по данному тарифу
- <указывается значение из поля "Минимальный % убывания платежей">, иначе красная рамка снимается. * - <указывается значение из поля "Минимальный % убывания платежей">, иначе красная рамка снимается.
* При красной рамке в данном поле нельзя осуществить расчет графика. * При красной рамке в данном поле нельзя осуществить расчет графика.
*/ */
/* eslint-enable */
reaction( reaction(
() => ({ () => ({
parmentsDecreasePercent: $calculation.element('tbxParmentsDecreasePercent').getValue(), parmentsDecreasePercent: $calculation.element('tbxParmentsDecreasePercent').getValue(),
tarifId: $calculation.element('selectTarif').getValue(), tarifId: $calculation.element('selectTarif').getValue(),
}), }),
async ({ parmentsDecreasePercent, tarifId }) => { async ({ parmentsDecreasePercent, tarifId }) => {
// eslint-disable-next-line @typescript-eslint/naming-convention
let evo_tarif: CRMTypes.GetTarifQuery['evo_tarif'] = null; let evo_tarif: CRMTypes.GetTarifQuery['evo_tarif'] = null;
if (tarifId) { if (tarifId) {
@ -35,9 +33,10 @@ export default function validationReactions({ store, apolloClient }: ReactionsCo
} }
$calculation.element('tbxParmentsDecreasePercent').validate({ $calculation.element('tbxParmentsDecreasePercent').validate({
invalid: invalid: Boolean(
!!evo_tarif?.evo_min_decreasing_perc && evo_tarif?.evo_min_decreasing_perc &&
parmentsDecreasePercent < evo_tarif?.evo_min_decreasing_perc, parmentsDecreasePercent < evo_tarif?.evo_min_decreasing_perc
),
message: `Процент убывания не может быть меньше минимального значения по данному тарифу - ${evo_tarif?.evo_min_decreasing_perc}`, message: `Процент убывания не может быть меньше минимального значения по данному тарифу - ${evo_tarif?.evo_min_decreasing_perc}`,
}); });
} }

View File

@ -1,10 +1,9 @@
/* eslint-disable @typescript-eslint/naming-convention */ /* eslint-disable @typescript-eslint/naming-convention */
import * as CRMTypes from '@/graphql/crm.types';
import type { ReactionsContext } from '@/process/types';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc'; import utc from 'dayjs/plugin/utc';
import { autorun, reaction } from 'mobx'; import { autorun, reaction } from 'mobx';
import * as CRMTypes from 'graphql/crm.types';
import type { ReactionsContext } from 'process/types';
import { makeDisposable, normalizeOptions } from 'tools'; import { makeDisposable, normalizeOptions } from 'tools';
dayjs.extend(utc); dayjs.extend(utc);
@ -28,11 +27,11 @@ export default function valuesReactions({ store, apolloClient }: ReactionsContex
let { let {
data: { evo_tarifs = [] }, data: { evo_tarifs = [] },
} = await apolloClient.query({ } = await apolloClient.query({
fetchPolicy: 'network-only',
query: CRMTypes.GetTarifsDocument, query: CRMTypes.GetTarifsDocument,
variables: { variables: {
currentDate, currentDate,
}, },
fetchPolicy: 'network-only',
}); });
if (product && leasingPeriod && deliveryTime && evo_tarifs) { if (product && leasingPeriod && deliveryTime && evo_tarifs) {

View File

@ -1,9 +1,10 @@
import { gql } from '@apollo/client';
import initializeApollo from 'apollo/client';
import { defaultValues } from 'config/tables/insurance-table';
import type * as CRMTypes from 'graphql/crm.types';
import type { GetQuoteDataInput, GetQuoteDataOutput } from '../load-kp/types'; import type { GetQuoteDataInput, GetQuoteDataOutput } from '../load-kp/types';
import initializeApollo from '@/apollo/client';
import { defaultValues } from '@/config/tables/insurance-table';
import type * as CRMTypes from '@/graphql/crm.types';
import { gql } from '@apollo/client';
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const DEFAULT_FINGAP_ROW = defaultValues.find((x) => x.key === 'fingap')!; const DEFAULT_FINGAP_ROW = defaultValues.find((x) => x.key === 'fingap')!;
const QUERY_GET_FINGAP_DATA_FROM_QUOTE = gql` const QUERY_GET_FINGAP_DATA_FROM_QUOTE = gql`
@ -20,10 +21,10 @@ const QUERY_GET_FINGAP_DATA_FROM_QUOTE = gql`
`; `;
type QuoteFingapProcessData = { type QuoteFingapProcessData = {
fingap: GetQuoteDataOutput['fingap'];
insurance: { insurance: {
values: Pick<GetQuoteDataOutput['insurance']['values'], 'fingap'>; values: Pick<GetQuoteDataOutput['insurance']['values'], 'fingap'>;
}; };
fingap: GetQuoteDataOutput['fingap'];
}; };
export default async function getFingapDataFromKP({ export default async function getFingapDataFromKP({
@ -43,7 +44,7 @@ export default async function getFingapDataFromKP({
}, },
}); });
const keys: Array<string> = []; const keys: string[] = [];
quote?.evo_product_risks?.forEach((x) => { quote?.evo_product_risks?.forEach((x) => {
if (x?.evo_addproduct_typeid) { if (x?.evo_addproduct_typeid) {
keys.push(x.evo_addproduct_typeid); keys.push(x.evo_addproduct_typeid);
@ -58,9 +59,9 @@ export default async function getFingapDataFromKP({
values: { values: {
fingap: { fingap: {
...DEFAULT_FINGAP_ROW, ...DEFAULT_FINGAP_ROW,
insTerm: quote?.evo_fingap_period || null,
insuranceCompany: quote?.evo_fingap_accountid || null, insuranceCompany: quote?.evo_fingap_accountid || null,
insured: quote?.evo_fingap_payer || null, insured: quote?.evo_fingap_payer || null,
insTerm: quote?.evo_fingap_period || null,
}, },
}, },
}, },

View File

@ -1,17 +1,15 @@
/* eslint-disable implicit-arrow-linebreak */
/* eslint-disable unicorn/consistent-function-scoping */
/* eslint-disable @typescript-eslint/naming-convention */ /* eslint-disable @typescript-eslint/naming-convention */
import { calculateFinGAP } from '@/api/core/query';
import type { RequestFinGAP } from '@/api/core/types';
import type { Risk } from '@/Components/Calculation/Form/Insurance/FinGAPTable/types';
import { STALE_TIME } from '@/constants/request';
import type * as CRMTypes from '@/graphql/crm.types';
import type { ReactionsContext } from '@/process/types';
import { gql } from '@apollo/client'; import { gql } from '@apollo/client';
import type { QueryFunctionContext } from '@tanstack/react-query'; import type { QueryFunctionContext } from '@tanstack/react-query';
import { calculateFinGAP } from 'api/core/query';
import type { RequestFinGAP } from 'api/core/types';
import type { Risk } from 'Components/Calculation/Form/Insurance/FinGAPTable/types';
import { STALE_TIME } from 'constants/request';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc'; import utc from 'dayjs/plugin/utc';
import type * as CRMTypes from 'graphql/crm.types';
import { comparer, reaction, toJS } from 'mobx'; import { comparer, reaction, toJS } from 'mobx';
import type { ReactionsContext } from 'process/types';
import { flatten } from 'tools/object'; import { flatten } from 'tools/object';
dayjs.extend(utc); dayjs.extend(utc);
@ -27,21 +25,21 @@ export default function commonReactions({ store, apolloClient, queryClient }: Re
); );
/** /**
Реакция на изменение Страховой компании у ФинГАП и Срока лизинга: * Реакция на изменение Страховой компании у ФинГАП и Срока лизинга:
*
Если Страхованя компания = Не выбрано, то * Если Страхованя компания = Не выбрано, то
*
Плательщик insuredFinGAP = ЛП (100 000 000) и закрыто для редактирования, * Плательщик insuredFinGAP = ЛП (100 000 000) и закрыто для редактирования,
Стоимость за первый период inscostFinGAP = 0 * Стоимость за первый период inscostFinGAP = 0
Срок страхования insTermFinGAP = 12 мес (100 000 000) и закрыто для редактирования * Срок страхования insTermFinGAP = 12 мес (100 000 000) и закрыто для редактирования
*
иначе * иначе
*
Плательщик insuredFinGAP = открыто для редактирования, * Плательщик insuredFinGAP = открыто для редактирования,
Стоимость за первый период inscostFinGAP = 0 * Стоимость за первый период inscostFinGAP = 0
Срок страхования insTermFinGAP = Если срок лизинга tbxLeasingPeriod < 13, * Срок страхования insTermFinGAP = Если срок лизинга tbxLeasingPeriod < 13,
то указываем Срок страхования insTermFinGAP = 12 мес * то указываем Срок страхования insTermFinGAP = 12 мес
и закрываем для редактирования, иначе открыто для редактирования * и закрываем для редактирования, иначе открыто для редактирования
*/ */
reaction( reaction(
() => { () => {
@ -62,7 +60,10 @@ export default function commonReactions({ store, apolloClient, queryClient }: Re
.setValue('insTerm', 100_000_000) .setValue('insTerm', 100_000_000)
.block('insured') .block('insured')
.block('insTerm'); .block('insTerm');
} else {
return;
}
$tables.insurance $tables.insurance
.row('fingap') .row('fingap')
.setValue('insured', 100_000_000) .setValue('insured', 100_000_000)
@ -75,7 +76,6 @@ export default function commonReactions({ store, apolloClient, queryClient }: Re
} else { } else {
$tables.insurance.row('fingap').unblock('insTerm'); $tables.insurance.row('fingap').unblock('insTerm');
} }
}
}, },
{ {
equals: comparer.shallow, equals: comparer.shallow,
@ -123,12 +123,12 @@ export default function commonReactions({ store, apolloClient, queryClient }: Re
const leasingPeriod = $calculation.element('tbxLeasingPeriod').getValue(); const leasingPeriod = $calculation.element('tbxLeasingPeriod').getValue();
return { return {
finGAPInsuranceCompany,
paymentsValues,
plPriceRub,
discountRub, discountRub,
finGAPInsuranceCompany,
firstPaymentRub, firstPaymentRub,
leasingPeriod, leasingPeriod,
paymentsValues,
plPriceRub,
}; };
}, },
async ({ async ({
@ -154,16 +154,18 @@ export default function commonReactions({ store, apolloClient, queryClient }: Re
}); });
const risks = evo_addproduct_types?.map( const risks = evo_addproduct_types?.map(
// prettier-ignore (evo_addproduct_type) =>
(evo_addproduct_type) => ({ ({
calcType: evo_addproduct_type?.evo_type_calc_cerebellum,
key: evo_addproduct_type?.evo_addproduct_typeid, key: evo_addproduct_type?.evo_addproduct_typeid,
keys: evo_addproduct_type?.evo_addproduct_types?.map(
(addproduct_type) => addproduct_type?.evo_addproduct_typeid
),
premium: 0,
premiumPerc: evo_addproduct_type?.evo_cost_service_provider_withoutnds,
riskId: evo_addproduct_type?.evo_addproduct_typeid, riskId: evo_addproduct_type?.evo_addproduct_typeid,
riskName: evo_addproduct_type?.evo_name, riskName: evo_addproduct_type?.evo_name,
calcType: evo_addproduct_type?.evo_type_calc_cerebellum,
premiumPerc: evo_addproduct_type?.evo_cost_service_provider_withoutnds,
sum: 0, sum: 0,
premium: 0,
keys: evo_addproduct_type?.evo_addproduct_types?.map((k) => k?.evo_addproduct_typeid),
} as Risk) } as Risk)
); );
@ -178,15 +180,16 @@ export default function commonReactions({ store, apolloClient, queryClient }: Re
percentPayment: payment, percentPayment: payment,
})), })),
values: { values: {
plPrice: plPriceRub,
discount: discountRub, discount: discountRub,
firstPayment: firstPaymentRub, firstPayment: firstPaymentRub,
leasingPeriod, leasingPeriod,
plPrice: plPriceRub,
premiumPerc: risk.premiumPerc || 0, premiumPerc: risk.premiumPerc || 0,
}, },
}; };
} }
// eslint-disable-next-line unicorn/consistent-function-scoping
function makeRequestGetFinGAP(request: RequestFinGAP) { function makeRequestGetFinGAP(request: RequestFinGAP) {
const queryCalculateFinGAP = (context: QueryFunctionContext) => const queryCalculateFinGAP = (context: QueryFunctionContext) =>
calculateFinGAP(request, context); calculateFinGAP(request, context);
@ -207,8 +210,8 @@ export default function commonReactions({ store, apolloClient, queryClient }: Re
).then((results) => { ).then((results) => {
const newRisks = risks.map((risk, i) => ({ const newRisks = risks.map((risk, i) => ({
...risk, ...risk,
sum: results.at(i)?.sum || 0,
premium: results.at(i)?.premium || 0, premium: results.at(i)?.premium || 0,
sum: results.at(i)?.sum || 0,
})); }));
$tables.fingap.setRisks(newRisks); $tables.fingap.setRisks(newRisks);
@ -216,8 +219,8 @@ export default function commonReactions({ store, apolloClient, queryClient }: Re
}, },
{ {
// Important: delay prohibits multiple reaction invocation // Important: delay prohibits multiple reaction invocation
equals: comparer.structural,
delay: 100, delay: 100,
equals: comparer.structural,
} }
); );
} }

Some files were not shown because too many files have changed in this diff Show More