diff --git a/.env b/.env
index eb78342..71125d0 100644
--- a/.env
+++ b/.env
@@ -2,9 +2,6 @@
USE_DEV_COLORS=
BASE_PATH=
-####### USERS ########
-USERS_SUPER=["akalinina","vchikalkin"]
-
####### URLS ########
URL_GET_USER_DIRECT=
URL_CRM_GRAPHQL_DIRECT=
diff --git a/apps/web/Components/Calculation/Form/Unlimited/config.ts b/apps/web/Components/Calculation/Form/Unlimited/config.ts
new file mode 100644
index 0000000..2c5cc34
--- /dev/null
+++ b/apps/web/Components/Calculation/Form/Unlimited/config.ts
@@ -0,0 +1,12 @@
+import type { FormTabRows } from '../../lib/render-rows';
+
+export const id = 'unlimited';
+export const title = 'Без ограничений';
+
+export const rows: FormTabRows = [
+ [['cbxDisableChecks', 'selectUser']],
+ [['selectTarif', 'tbxCreditRate', 'selectRate']],
+ [['tbxMinPriceChange', 'tbxMaxPriceChange']],
+ [['tbxImporterRewardPerc', 'tbxImporterRewardRub']],
+ [['tbxBonusCoefficient', 'tbxComissionRub', 'tbxComissionPerc']],
+];
diff --git a/apps/web/Components/Calculation/Form/Unlimited/index.jsx b/apps/web/Components/Calculation/Form/Unlimited/index.jsx
new file mode 100644
index 0000000..91f340f
--- /dev/null
+++ b/apps/web/Components/Calculation/Form/Unlimited/index.jsx
@@ -0,0 +1,12 @@
+import renderFormRows from '../../lib/render-rows';
+import { id, rows, title } from './config';
+
+function Unlimited() {
+ return renderFormRows(rows);
+}
+
+export default {
+ Component: Unlimited,
+ id,
+ title,
+};
diff --git a/apps/web/Components/Calculation/Form/index.jsx b/apps/web/Components/Calculation/Form/index.jsx
index 175cb11..7ba84b9 100644
--- a/apps/web/Components/Calculation/Form/index.jsx
+++ b/apps/web/Components/Calculation/Form/index.jsx
@@ -5,12 +5,22 @@ import Leasing from './Leasing';
import LeasingObject from './LeasingObject';
import Payments from './Payments';
import SupplierAgent from './SupplierAgent';
+import Unlimited from './Unlimited';
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,
+ Unlimited,
+];
const Wrapper = styled(Background)`
padding: 4px 6px;
@@ -32,17 +42,19 @@ const ComponentWrapper = styled.div`
}
`;
-function Form() {
+function Form({ prune }) {
return (
- {formTabs.map(({ id, title, Component }) => (
-
-
-
-
-
- ))}
+ {formTabs
+ .filter((tab) => !prune?.includes(tab.id))
+ .map(({ id, title, Component }) => (
+
+
+
+
+
+ ))}
);
diff --git a/apps/web/Components/Calculation/config/elements-components.ts b/apps/web/Components/Calculation/config/elements-components.ts
index 56d946a..774b1de 100644
--- a/apps/web/Components/Calculation/config/elements-components.ts
+++ b/apps/web/Components/Calculation/config/elements-components.ts
@@ -131,6 +131,7 @@ const components = wrapComponentsMap({
tbxBonusCoefficient: e.InputNumber,
selectLeasingWithoutKasko: e.Select,
tbxVIN: e.Input,
+ selectUser: e.Select,
/** Readonly Elements */
labelLeaseObjectRisk: e.Text,
diff --git a/apps/web/Components/Calculation/config/elements-props.tsx b/apps/web/Components/Calculation/config/elements-props.tsx
index 95c1a7c..ddc752b 100644
--- a/apps/web/Components/Calculation/config/elements-props.tsx
+++ b/apps/web/Components/Calculation/config/elements-props.tsx
@@ -444,6 +444,10 @@ const props: Partial = {
direction: 'vertical',
},
},
+ selectUser: {
+ showSearch: true,
+ optionFilterProp: 'label',
+ },
};
export default props;
diff --git a/apps/web/Components/Calculation/config/elements-titles.ts b/apps/web/Components/Calculation/config/elements-titles.ts
index ba37e87..81b3f67 100644
--- a/apps/web/Components/Calculation/config/elements-titles.ts
+++ b/apps/web/Components/Calculation/config/elements-titles.ts
@@ -125,6 +125,7 @@ const titles: Record = {
tbxBonusCoefficient: 'Коэффициент снижения бонуса',
selectLeasingWithoutKasko: 'Лизинг без КАСКО',
tbxVIN: 'VIN',
+ selectUser: 'Пользователь',
/** Link Elements */
linkDownloadKp: '',
diff --git a/apps/web/Components/Calculation/config/elements-types.ts b/apps/web/Components/Calculation/config/elements-types.ts
index 8142aa5..de258b4 100644
--- a/apps/web/Components/Calculation/config/elements-types.ts
+++ b/apps/web/Components/Calculation/config/elements-types.ts
@@ -162,6 +162,7 @@ const types = wrapElementsTypes({
tbxBonusCoefficient: t.Value,
selectLeasingWithoutKasko: t.Options,
tbxVIN: t.Value,
+ selectUser: t.Options,
labelLeaseObjectRisk: t.Readonly,
tbxInsKaskoPriceLeasePeriod: t.Readonly,
diff --git a/apps/web/Components/Calculation/config/map/values.ts b/apps/web/Components/Calculation/config/map/values.ts
index 5271277..d3fe420 100644
--- a/apps/web/Components/Calculation/config/map/values.ts
+++ b/apps/web/Components/Calculation/config/map/values.ts
@@ -128,6 +128,7 @@ const elementsToValues = wrapElementsMap({
tbxMinPriceChange: 'minPriceChange',
tbxBonusCoefficient: 'bonusCoefficient',
tbxVIN: 'vin',
+ selectUser: 'user',
/** Readonly Elements */
labelLeaseObjectRisk: 'leaseObjectRiskName',
diff --git a/apps/web/Components/Layout/Logo.jsx b/apps/web/Components/Layout/Logo.jsx
index 509569f..7edee39 100644
--- a/apps/web/Components/Layout/Logo.jsx
+++ b/apps/web/Components/Layout/Logo.jsx
@@ -1,10 +1,13 @@
/* eslint-disable react/forbid-component-props */
import styles from './Logo.module.css';
+import { useStore } from '@/stores/hooks';
+import getColors from '@/styles/colors';
import { min } from '@/styles/mq';
+import { observer } from 'mobx-react-lite';
import Image from 'next/image';
import logo from 'public/assets/images/logo-primary.svg';
import styled from 'styled-components';
-import { Flex } from 'ui';
+import { Flex, Tag } from 'ui';
const ImageWrapper = styled.div`
width: 100px;
@@ -26,13 +29,41 @@ const LogoText = styled.h3`
}
`;
+const TagWrapper = styled.div`
+ font-family: 'Montserrat';
+ font-weight: 500;
+ * {
+ font-size: 0.7rem;
+ }
+`;
+
+const { COLOR_PRIMARY } = getColors();
+
+const UnlimitedTag = observer(() => {
+ const { $process } = useStore();
+ if ($process.has('Unlimited')) {
+ return (
+
+
+ без ограничений
+
+
+ );
+ }
+
+ return false;
+});
+
function Logo() {
return (
- Лизинговый Калькулятор
+
+ Лизинговый Калькулятор
+
+
);
}
diff --git a/apps/web/Components/Layout/Page.jsx b/apps/web/Components/Layout/Page.jsx
new file mode 100644
index 0000000..b2a6439
--- /dev/null
+++ b/apps/web/Components/Layout/Page.jsx
@@ -0,0 +1,27 @@
+import { min } from '@/styles/mq';
+import styled from 'styled-components';
+import { Box } from 'ui/grid';
+
+export const Grid = styled(Box)`
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+
+ ${min('laptop')} {
+ display: grid;
+ align-items: flex-start;
+ grid-template-columns: 2fr 1fr;
+ }
+
+ ${min('laptop-hd')} {
+ grid-template-columns: 2fr 1fr 1.5fr;
+ }
+
+ ${min('desktop')} {
+ margin: 8px 5%;
+ }
+
+ ${min('desktop-xl')} {
+ margin: 8px 10%;
+ }
+`;
diff --git a/apps/web/api/core/types/calculate.ts b/apps/web/api/core/types/calculate.ts
index 77887b5..72d500a 100644
--- a/apps/web/api/core/types/calculate.ts
+++ b/apps/web/api/core/types/calculate.ts
@@ -138,8 +138,13 @@ const AdditionalDataSchema = z.object({
export type AdditionalData = z.infer;
+const flagsSchema = z.object({
+ DISABLE_CHECKS_RESULTS: z.boolean(),
+});
+
export const RequestCalculateSchema = z.object({
additionalData: AdditionalDataSchema,
+ flags: flagsSchema.optional(),
preparedPayments: PreparedPaymentSchema,
preparedValues: PreparedValuesSchema,
});
diff --git a/apps/web/api/user/tools.ts b/apps/web/api/user/tools.ts
index 3539d54..815775c 100644
--- a/apps/web/api/user/tools.ts
+++ b/apps/web/api/user/tools.ts
@@ -1,13 +1,8 @@
import type { User } from './types';
-import { publicRuntimeConfigSchema } from '@/config/schema/runtime-config';
-import getConfig from 'next/config';
-
-const { publicRuntimeConfig } = getConfig();
-const { USERS_SUPER } = publicRuntimeConfigSchema.parse(publicRuntimeConfig);
+import { usersSuper } from '@/config/users';
export function love(user: User) {
- const superUsers: string[] = JSON.parse(USERS_SUPER);
- if (superUsers?.includes(user.username)) user.displayName += '🧡';
+ if (usersSuper?.includes(user.username)) user.displayName += '🧡';
return user;
}
diff --git a/apps/web/config/default-options.ts b/apps/web/config/default-options.ts
index 10c5b9b..ab4c2a5 100644
--- a/apps/web/config/default-options.ts
+++ b/apps/web/config/default-options.ts
@@ -493,6 +493,7 @@ const defaultOptions: CalculationOptions = {
tbxBonusCoefficient: [],
selectLeasingWithoutKasko: [],
tbxVIN: [],
+ selectUser: [],
};
export default defaultOptions;
diff --git a/apps/web/config/default-statuses.ts b/apps/web/config/default-statuses.ts
index ec3c327..dbdcb41 100644
--- a/apps/web/config/default-statuses.ts
+++ b/apps/web/config/default-statuses.ts
@@ -86,6 +86,7 @@ const defaultStatuses: CalculationStatuses = {
selectTelematic: 'Default',
selectTownRegistration: 'Default',
selectTracker: 'Default',
+ selectUser: 'Default',
tbxAddEquipmentPrice: 'Default',
tbxBonusCoefficient: 'Default',
tbxCalcBrokerRewardSum: 'Disabled',
diff --git a/apps/web/config/default-values.ts b/apps/web/config/default-values.ts
index 5050599..1f7bb79 100644
--- a/apps/web/config/default-values.ts
+++ b/apps/web/config/default-values.ts
@@ -137,6 +137,7 @@ const defaultValues: CalculationValues = {
vehicleTaxInYear: 0,
withTrailer: false,
vin: null,
+ user: null,
};
export default defaultValues;
diff --git a/apps/web/config/schema/env.js b/apps/web/config/schema/env.js
index 358a120..3508c8e 100644
--- a/apps/web/config/schema/env.js
+++ b/apps/web/config/schema/env.js
@@ -10,7 +10,6 @@ const envSchema = z.object({
URL_CRM_GRAPHQL_DIRECT: z.string(),
URL_GET_USER_DIRECT: z.string(),
USE_DEV_COLORS: z.unknown().optional().transform(Boolean),
- USERS_SUPER: z.string().optional().default(''),
});
module.exports = envSchema;
diff --git a/apps/web/config/schema/runtime-config.js b/apps/web/config/schema/runtime-config.js
index 40bf145..1f59d27 100644
--- a/apps/web/config/schema/runtime-config.js
+++ b/apps/web/config/schema/runtime-config.js
@@ -3,7 +3,6 @@ const envSchema = require('./env');
const publicRuntimeConfigSchema = envSchema.pick({
BASE_PATH: true,
USE_DEV_COLORS: true,
- USERS_SUPER: true,
});
const serverRuntimeConfigSchema = envSchema.pick({
diff --git a/apps/web/config/schema/values.ts b/apps/web/config/schema/values.ts
index d924ccd..e1bd311 100644
--- a/apps/web/config/schema/values.ts
+++ b/apps/web/config/schema/values.ts
@@ -123,6 +123,7 @@ const ValuesSchema = z.object({
vehicleTaxInYear: z.number(),
withTrailer: z.boolean(),
vin: z.string().nullable(),
+ user: z.string().nullable(),
/**
* Link Values
diff --git a/apps/web/config/users.js b/apps/web/config/users.js
new file mode 100644
index 0000000..59b581b
--- /dev/null
+++ b/apps/web/config/users.js
@@ -0,0 +1,3 @@
+export const unlimitedRoles = ['Калькулятор без ограничений'];
+export const defaultRoles = ['МПЛ'];
+export const usersSuper = ['akalinina', 'vchikalkin'];
diff --git a/apps/web/graphql/crm.query.graphql b/apps/web/graphql/crm.query.graphql
index e89768c..6847f24 100644
--- a/apps/web/graphql/crm.query.graphql
+++ b/apps/web/graphql/crm.query.graphql
@@ -639,3 +639,12 @@ query GetInsuranceCompanies {
label: name
}
}
+
+query GetRoles($roleName: String) {
+ roles(name: $roleName) {
+ systemusers {
+ label: fullname
+ value: domainname
+ }
+ }
+}
diff --git a/apps/web/graphql/crm.types.ts b/apps/web/graphql/crm.types.ts
index 361d813..4ea012a 100644
--- a/apps/web/graphql/crm.types.ts
+++ b/apps/web/graphql/crm.types.ts
@@ -470,6 +470,13 @@ export type GetInsuranceCompaniesQueryVariables = Exact<{ [key: string]: never;
export type GetInsuranceCompaniesQuery = { __typename?: 'Query', accounts: Array<{ __typename?: 'account', evo_type_ins_policy: Array | null, evo_evokasko_access: boolean | null, evo_inn: string | null, value: string | null, label: string | null } | null> | null };
+export type GetRolesQueryVariables = Exact<{
+ roleName: InputMaybe;
+}>;
+
+
+export type GetRolesQuery = { __typename?: 'Query', roles: Array<{ __typename?: 'role', systemusers: Array<{ __typename?: 'systemuser', label: string | null, value: string | null } | null> | null } | null> | null };
+
export type GetQuoteAddProductDataQueryVariables = Exact<{
quoteId: Scalars['Uuid'];
}>;
@@ -642,6 +649,7 @@ export const GetInsNsibTypesDocument = {"kind":"Document","definitions":[{"kind"
export const GetLeasingWithoutKaskoTypesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetLeasingWithoutKaskoTypes"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"currentDate"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"DateTime"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"evo_addproduct_types"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"statecode"},"value":{"kind":"IntValue","value":"0"}},{"kind":"Argument","name":{"kind":"Name","value":"evo_product_type"},"value":{"kind":"IntValue","value":"100000007"}},{"kind":"Argument","name":{"kind":"Name","value":"evo_datefrom_param"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"lte"},"value":{"kind":"Variable","name":{"kind":"Name","value":"currentDate"}}}]}},{"kind":"Argument","name":{"kind":"Name","value":"evo_dateto_param"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"gte"},"value":{"kind":"Variable","name":{"kind":"Name","value":"currentDate"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CoreAddProductTypesFields"}},{"kind":"Field","name":{"kind":"Name","value":"evo_product_type"}},{"kind":"Field","name":{"kind":"Name","value":"evo_min_period"}},{"kind":"Field","name":{"kind":"Name","value":"evo_max_period"}},{"kind":"Field","name":{"kind":"Name","value":"evo_min_price"}},{"kind":"Field","name":{"kind":"Name","value":"evo_max_price"}},{"kind":"Field","name":{"kind":"Name","value":"evo_leasingobject_types"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"evo_leasingobject_typeid"}}]}},{"kind":"Field","name":{"kind":"Name","value":"evo_visible_calc"}},{"kind":"Field","name":{"kind":"Name","value":"evo_min_first_payment_perc"}},{"kind":"Field","name":{"kind":"Name","value":"evo_max_first_payment_perc"}},{"kind":"Field","name":{"kind":"Name","value":"evo_models"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"evo_modelid"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CoreAddProductTypesFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"evo_addproduct_type"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"evo_graph_price"}},{"kind":"Field","alias":{"kind":"Name","value":"label"},"name":{"kind":"Name","value":"evo_name"}},{"kind":"Field","alias":{"kind":"Name","value":"value"},"name":{"kind":"Name","value":"evo_addproduct_typeid"}}]}}]} as unknown as DocumentNode;
export const GetInsuranceCompanyDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetInsuranceCompany"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"accountId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Uuid"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"account"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"accountid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"accountId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"evo_osago_with_kasko"}}]}}]}}]} as unknown as DocumentNode;
export const GetInsuranceCompaniesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetInsuranceCompanies"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accounts"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"evo_account_type"},"value":{"kind":"ListValue","values":[{"kind":"IntValue","value":"100000002"}]}},{"kind":"Argument","name":{"kind":"Name","value":"statecode"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"evo_type_ins_policy"}},{"kind":"Field","name":{"kind":"Name","value":"evo_evokasko_access"}},{"kind":"Field","name":{"kind":"Name","value":"evo_inn"}},{"kind":"Field","alias":{"kind":"Name","value":"value"},"name":{"kind":"Name","value":"accountid"}},{"kind":"Field","alias":{"kind":"Name","value":"label"},"name":{"kind":"Name","value":"name"}}]}}]}}]} as unknown as DocumentNode;
+export const GetRolesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetRoles"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"roleName"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"roles"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"name"},"value":{"kind":"Variable","name":{"kind":"Name","value":"roleName"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"systemusers"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","alias":{"kind":"Name","value":"label"},"name":{"kind":"Name","value":"fullname"}},{"kind":"Field","alias":{"kind":"Name","value":"value"},"name":{"kind":"Name","value":"domainname"}}]}}]}}]}}]} as unknown as DocumentNode;
export const GetQuoteAddProductDataDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetQuoteAddProductData"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"quoteId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Uuid"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"quote"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"quoteId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"quoteId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"evo_addproduct_types"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"evo_product_type"}},{"kind":"Field","name":{"kind":"Name","value":"evo_addproduct_typeid"}}]}}]}}]}}]} as unknown as DocumentNode;
export const GetQuoteBonusDataDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetQuoteBonusData"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"quoteId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Uuid"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"quote"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"quoteId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"quoteId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"evo_sale_bonus"}}]}}]}}]} as unknown as DocumentNode;
export const GetQuoteConfiguratorDataDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetQuoteConfiguratorData"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"quoteId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Uuid"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"quote"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"quoteId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"quoteId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"evo_baseproductid"}},{"kind":"Field","name":{"kind":"Name","value":"evo_client_typeid"}},{"kind":"Field","name":{"kind":"Name","value":"evo_msfo_irr"}}]}}]}}]} as unknown as DocumentNode;
diff --git a/apps/web/pages/_document.jsx b/apps/web/pages/_document.jsx
index 48f85de..9a4eda7 100644
--- a/apps/web/pages/_document.jsx
+++ b/apps/web/pages/_document.jsx
@@ -36,7 +36,7 @@ export default class MyDocument extends Document {
-
+
{metaFavicon}
diff --git a/apps/web/pages/index.jsx b/apps/web/pages/index.jsx
index 158869c..b6d9a47 100644
--- a/apps/web/pages/index.jsx
+++ b/apps/web/pages/index.jsx
@@ -2,41 +2,16 @@ import { getUser } from '@/api/user/query';
import initializeApollo from '@/apollo/client';
import * as Calculation from '@/Components/Calculation';
import { Error } from '@/Components/Common/Error';
+import { Grid } from '@/Components/Layout/Page';
import Output from '@/Components/Output';
+import { defaultRoles } from '@/config/users';
import * as CRMTypes from '@/graphql/crm.types';
import { useInsuranceData, useMainData, useReactions } from '@/process/hooks';
import { getInitialData } from '@/process/hooks/init';
-import { min } from '@/styles/mq';
import { dehydrate, QueryClient } from '@tanstack/react-query';
import Head from 'next/head';
-import styled from 'styled-components';
-import { Box } from 'ui/grid';
-const Grid = styled(Box)`
- display: flex;
- flex-direction: column;
- gap: 10px;
-
- ${min('laptop')} {
- display: grid;
- align-items: flex-start;
- grid-template-columns: 2fr 1fr;
- }
-
- ${min('laptop-hd')} {
- grid-template-columns: 2fr 1fr 1.5fr;
- }
-
- ${min('desktop')} {
- margin: 8px 5%;
- }
-
- ${min('desktop-xl')} {
- margin: 8px 10%;
- }
-`;
-
-function Home(props) {
+export default function Home(props) {
useMainData();
useInsuranceData();
useReactions();
@@ -48,65 +23,69 @@ function Home(props) {
Лизинговый калькулятор - Эволюция
-
+
);
}
-/** @type {import('next').GetServerSideProps} */
-export const getServerSideProps = async ({ req }) => {
- const { cookie = '' } = req.headers;
+export const makeGetServerSideProps = ({ roles }) =>
+ /** @type {import('next').GetServerSideProps} */
+ (
+ async function ({ req }) {
+ const { cookie = '' } = req.headers;
- const queryClient = new QueryClient();
+ const queryClient = new QueryClient();
- const user = await queryClient.fetchQuery(['user'], ({ signal }) =>
- getUser({
- headers: {
- cookie,
- },
- signal,
- })
+ const user = await queryClient.fetchQuery(['user'], ({ signal }) =>
+ getUser({
+ headers: {
+ cookie,
+ },
+ signal,
+ })
+ );
+
+ const apolloClient = initializeApollo();
+
+ try {
+ const {
+ data: { systemuser },
+ } = await apolloClient.query({
+ fetchPolicy: 'network-only',
+ query: CRMTypes.GetSystemUserDocument,
+ variables: {
+ domainname: user.domainName,
+ },
+ });
+
+ if (!systemuser?.roles?.some((x) => x?.name && roles.includes(x.name))) {
+ return {
+ props: { statusCode: 403 },
+ };
+ }
+ const { values, options } = await getInitialData(apolloClient, user);
+
+ return {
+ props: {
+ calculation: {
+ options,
+ values,
+ },
+ initialApolloState: apolloClient.cache.extract(),
+ initialQueryState: dehydrate(queryClient),
+ statusCode: 200,
+ },
+ };
+ } catch (error) {
+ return {
+ props: {
+ error: JSON.stringify(error),
+ statusCode: 500,
+ },
+ };
+ }
+ }
);
- const apolloClient = initializeApollo();
-
- try {
- const {
- data: { systemuser },
- } = await apolloClient.query({
- query: CRMTypes.GetSystemUserDocument,
- variables: {
- domainname: user.domainName,
- },
- });
-
- if (!systemuser.roles.some((x) => x.name === 'МПЛ')) {
- return {
- props: { statusCode: 403 },
- };
- }
- const { values, options } = await getInitialData(apolloClient, user);
-
- return {
- props: {
- calculation: {
- options,
- values,
- },
- initialApolloState: apolloClient.cache.extract(),
- initialQueryState: dehydrate(queryClient),
- statusCode: 200,
- },
- };
- } catch (error) {
- return {
- props: {
- error: JSON.stringify(error),
- statusCode: 500,
- },
- };
- }
-};
-
-export default Home;
+export const getServerSideProps = makeGetServerSideProps({ roles: defaultRoles });
diff --git a/apps/web/pages/unlimited.jsx b/apps/web/pages/unlimited.jsx
new file mode 100644
index 0000000..d5d8c4f
--- /dev/null
+++ b/apps/web/pages/unlimited.jsx
@@ -0,0 +1,37 @@
+import { makeGetServerSideProps } from '.';
+import * as Calculation from '@/Components/Calculation';
+import { Error } from '@/Components/Common/Error';
+import { Grid } from '@/Components/Layout/Page';
+import Output from '@/Components/Output';
+import { unlimitedRoles } from '@/config/users';
+import { useGetUsers, useInsuranceData, useMainData, useReactions } from '@/process/hooks';
+import { useStore } from '@/stores/hooks';
+import Head from 'next/head';
+
+export default function Unlimited(props) {
+ const store = useStore();
+ store.$process.add('Unlimited');
+
+ useMainData();
+ useGetUsers();
+ useInsuranceData();
+ useReactions();
+
+ if (props.statusCode !== 200) return ;
+
+ return (
+
+
+ Лизинговый калькулятор без ограничений - Эволюция
+
+
+
+
+
+
+ );
+}
+
+export const getServerSideProps = makeGetServerSideProps({
+ roles: unlimitedRoles,
+});
diff --git a/apps/web/process/configurator/reactions/index.ts b/apps/web/process/configurator/reactions/index.ts
index e294884..1b87c74 100644
--- a/apps/web/process/configurator/reactions/index.ts
+++ b/apps/web/process/configurator/reactions/index.ts
@@ -1,3 +1,4 @@
export { default as filters } from './filters';
+export { default as unlimited } from './unlimited';
export { default as validation } from './validation';
export { default as values } from './values';
diff --git a/apps/web/process/configurator/reactions/unlimited.ts b/apps/web/process/configurator/reactions/unlimited.ts
new file mode 100644
index 0000000..7dfd80c
--- /dev/null
+++ b/apps/web/process/configurator/reactions/unlimited.ts
@@ -0,0 +1,35 @@
+import * as CRMTypes from '@/graphql/crm.types';
+import type { ProcessContext } from '@/process/types';
+import { reaction } from 'mobx';
+import { makeDisposable, normalizeOptions } from 'tools';
+
+export default function unlimitedReactions({ store, apolloClient }: ProcessContext) {
+ const { $calculation, $process } = store;
+
+ makeDisposable(
+ () =>
+ reaction(
+ () => $calculation.element('selectUser').getValue(),
+ async (domainname) => {
+ const {
+ data: { leads },
+ } = await apolloClient.query({
+ query: CRMTypes.GetLeadsDocument,
+ variables: { domainname },
+ });
+
+ $calculation.element('selectLead').setOptions(normalizeOptions(leads));
+
+ const {
+ data: { opportunities },
+ } = await apolloClient.query({
+ query: CRMTypes.GetOpportunitiesDocument,
+ variables: { domainname },
+ });
+
+ $calculation.element('selectOpportunity').setOptions(normalizeOptions(opportunities));
+ }
+ ),
+ () => !$process.has('Unlimited')
+ );
+}
diff --git a/apps/web/process/hooks/init/get-users.js b/apps/web/process/hooks/init/get-users.js
new file mode 100644
index 0000000..bd70a21
--- /dev/null
+++ b/apps/web/process/hooks/init/get-users.js
@@ -0,0 +1,37 @@
+import * as CRMTypes from '@/graphql/crm.types';
+import { useStore } from '@/stores/hooks';
+import { useApolloClient } from '@apollo/client';
+import { useEffect } from 'react';
+import { normalizeOptions } from 'tools';
+
+/**
+ * @param {import('@apollo/client').ApolloClient} apolloClient
+ * @param {*} onCompleted
+ */
+export function getUsers({ query }, onCompleted) {
+ query({
+ query: CRMTypes.GetRolesDocument,
+ variables: { roleName: 'МПЛ' },
+ }).then(({ data }) => {
+ const users = data.roles?.flatMap((x) => x?.systemusers);
+ onCompleted({
+ selectUser: users,
+ });
+ });
+}
+
+export function useGetUsers() {
+ const { $calculation } = useStore();
+ const apolloClient = useApolloClient();
+
+ function handleOnCompleted(options) {
+ Object.keys(options).forEach((elementName) => {
+ const elementOptions = options[elementName];
+ $calculation.element(elementName).setOptions(normalizeOptions(elementOptions));
+ });
+ }
+
+ useEffect(() => {
+ getUsers(apolloClient, handleOnCompleted);
+ }, []);
+}
diff --git a/apps/web/process/hooks/init/index.js b/apps/web/process/hooks/init/index.js
index eee9f13..2cf7203 100644
--- a/apps/web/process/hooks/init/index.js
+++ b/apps/web/process/hooks/init/index.js
@@ -1,3 +1,4 @@
export * from './get-initial-data';
export * from './get-insurance-data';
export * from './get-main-data';
+export * from './get-users';
diff --git a/apps/web/process/types.ts b/apps/web/process/types.ts
index b13166d..98cc755 100644
--- a/apps/web/process/types.ts
+++ b/apps/web/process/types.ts
@@ -9,7 +9,7 @@ export type ProcessContext = {
queryClient: QueryClient;
store: RootStore;
trpcClient: TRPCPureClient;
- user: User | undefined;
+ user: Pick | undefined;
};
export type Process = {
diff --git a/apps/web/server/middleware.ts b/apps/web/server/middleware.ts
index 553e146..fedce85 100644
--- a/apps/web/server/middleware.ts
+++ b/apps/web/server/middleware.ts
@@ -1,19 +1,33 @@
import { t } from './trpc';
+import initializeApollo from '@/apollo/client';
+import { unlimitedRoles } from '@/config/users';
+import * as CRMTypes from '@/graphql/crm.types';
import { TRPCError } from '@trpc/server';
/**
* @see https://trpc.io/docs/v10/middlewares
*/
-export const userMiddleware = t.middleware(({ ctx, next }) => {
+export const userMiddleware = t.middleware(async ({ ctx, next }) => {
if (process.env.NODE_ENV !== 'development' && !ctx.user) {
throw new TRPCError({
code: 'UNAUTHORIZED',
});
}
+ const apolloClient = initializeApollo();
+
+ const {
+ data: { systemuser },
+ } = await apolloClient.query({
+ query: CRMTypes.GetSystemUserDocument,
+ variables: {
+ domainname: ctx.user.domainName,
+ },
+ });
+
return next({
ctx: {
- isAdmin: false,
+ unlimited: systemuser?.roles?.some((x) => x?.name && unlimitedRoles.includes(x.name)),
},
});
});
diff --git a/apps/web/server/routers/calculate/index.ts b/apps/web/server/routers/calculate/index.ts
index f4c7a6c..50aceb9 100644
--- a/apps/web/server/routers/calculate/index.ts
+++ b/apps/web/server/routers/calculate/index.ts
@@ -4,6 +4,7 @@ import { transformCalculateResults } from './lib/transform';
import { validate } from './lib/validation';
import { CalculateInputSchema, CalculateOutputSchema } from './types';
import { calculate } from '@/api/core/query';
+import type { User } from '@/api/user/types';
import initializeApollo from '@/apollo/client';
import { protectedProcedure } from '@/server/procedure';
import { QueryClient } from '@tanstack/react-query';
@@ -16,30 +17,37 @@ export const calculateRouter = router({
const apolloClient = initializeApollo();
const queryClient = new QueryClient();
- const validationResult = await validate({
- context: {
- apolloClient,
- queryClient,
- user: ctx.user,
- },
- input,
- });
+ if (ctx.unlimited === false) {
+ const validationResult = await validate({
+ context: {
+ apolloClient,
+ queryClient,
+ user: ctx.user,
+ },
+ input,
+ });
- if (validationResult.success === false) {
- return {
- error: validationResult.error,
- success: false,
- };
+ if (validationResult.success === false) {
+ return {
+ error: validationResult.error,
+ success: false,
+ };
+ }
+ }
+
+ let user: Pick = { domainName: ctx.user.domainName };
+ if (ctx.unlimited && input.values.user) {
+ user = { domainName: input.values.user };
}
const requestData = await createRequestData({
context: {
apolloClient,
queryClient,
- user: ctx.user,
+ ...ctx,
+ user,
},
input,
- user: ctx.user,
});
const calculateResult = await calculate(requestData);
diff --git a/apps/web/server/routers/calculate/lib/request.ts b/apps/web/server/routers/calculate/lib/request.ts
index e1b3b1f..1a9fb37 100644
--- a/apps/web/server/routers/calculate/lib/request.ts
+++ b/apps/web/server/routers/calculate/lib/request.ts
@@ -1,7 +1,6 @@
/* eslint-disable sonarjs/cognitive-complexity */
import type { CalculateInput, Context } from '../types';
import type * as CoreTypes from '@/api/core/types';
-import type { User } from '@/api/user/types';
import { ESN, NSIB_MAX, VAT } from '@/constants/values';
import * as CRMTypes from '@/graphql/crm.types';
import helper from '@/process/calculate/lib/helper';
@@ -13,9 +12,8 @@ import { max, sum } from 'radash';
dayjs.extend(utc);
type Input = {
- context: Context;
+ context: Context & { unlimited?: boolean };
input: CalculateInput;
- user: User;
};
type PreparedValuesGetters = {
@@ -29,9 +27,8 @@ type AdditionalDataGetters = {
export async function createRequestData({
context,
input,
- user,
}: Input): Promise {
- const { apolloClient } = context;
+ const { apolloClient, user, unlimited } = context;
const { values, insurance, payments } = input;
const { RUB } = createCurrencyUtility({ apolloClient });
@@ -1232,6 +1229,9 @@ export async function createRequestData({
return {
additionalData,
+ flags: {
+ DISABLE_CHECKS_RESULTS: unlimited,
+ },
preparedPayments,
preparedValues,
};
diff --git a/apps/web/server/routers/quote/index.ts b/apps/web/server/routers/quote/index.ts
index 100c765..4f8b854 100644
--- a/apps/web/server/routers/quote/index.ts
+++ b/apps/web/server/routers/quote/index.ts
@@ -13,6 +13,7 @@ import {
} from './types';
import { calculate } from '@/api/core/query';
import { createKP } from '@/api/crm/query';
+import type { User } from '@/api/user/types';
import initializeApollo from '@/apollo/client';
import defaultValues from '@/config/default-values';
import * as insuranceTable from '@/config/tables/insurance-table';
@@ -88,30 +89,37 @@ export const quoteRouter = router({
const apolloClient = initializeApollo();
const queryClient = new QueryClient();
- const validationResult = await validate({
- context: {
- apolloClient,
- queryClient,
- user: ctx.user,
- },
- input,
- });
+ if (ctx.unlimited === false) {
+ const validationResult = await validate({
+ context: {
+ apolloClient,
+ queryClient,
+ user: ctx.user,
+ },
+ input,
+ });
- if (validationResult.success === false) {
- return {
- error: validationResult.error,
- success: false,
- };
+ if (validationResult.success === false) {
+ return {
+ error: validationResult.error,
+ success: false,
+ };
+ }
+ }
+
+ let user: Pick = { domainName: ctx.user.domainName };
+ if (ctx.unlimited && input.values.user) {
+ user = { domainName: input.values.user };
}
const requestData = await createRequestData({
context: {
apolloClient,
queryClient,
- user: ctx.user,
+ ...ctx,
+ user,
},
input,
- user: ctx.user,
});
const calculateResult = await calculate(requestData);
diff --git a/packages/ui/elements/index.ts b/packages/ui/elements/index.ts
index ae1c1d3..7b14df4 100644
--- a/packages/ui/elements/index.ts
+++ b/packages/ui/elements/index.ts
@@ -13,5 +13,6 @@ export { default as Segmented } from './Segmented';
export { default as Select } from './Select';
export { default as Switch } from './Switch';
export { default as Table } from './Table';
+export * from './tag';
export { default as Text } from './Text';
export { default as Tooltip } from './Tooltip';
diff --git a/packages/ui/elements/tag.js b/packages/ui/elements/tag.js
new file mode 100644
index 0000000..2bfffd1
--- /dev/null
+++ b/packages/ui/elements/tag.js
@@ -0,0 +1 @@
+export { Tag } from 'antd';