From 3977daebe53b3d18aad6cc1fe95cf0eacae1a14d Mon Sep 17 00:00:00 2001 From: Grog Date: Mon, 12 Oct 2026 09:45:31 +0300 Subject: [PATCH] added forms for catalogue jur --- src/layouts/CatalogueJur.tsx | 50 +++- src/services/api/directories/catalogue_jur.ts | 40 +++- .../catalogueJurSlice/catalogueJurSlice.ts | 17 +- src/store/slices/catalogueJurSlice/types.ts | 1 + src/types/catalogueJur/catalogueJur.ts | 40 +++- .../CatalogueJurForm/CatalogueJurForm.tsx | 217 ++++++++++++++++++ .../CatalogueJurTable/CatalogueJurTable.tsx | 148 ++++++++++-- src/widgets/CatalogueJurTable/config.tsx | 7 +- .../MoveCatalogueJurForm.tsx | 19 +- .../WithdrawCatalogueJurForm.tsx | 120 ++++++++++ 10 files changed, 607 insertions(+), 52 deletions(-) create mode 100644 src/widgets/CatalogueJurForm/CatalogueJurForm.tsx create mode 100644 src/widgets/WithdrawCatalogueJurForm/WithdrawCatalogueJurForm.tsx diff --git a/src/layouts/CatalogueJur.tsx b/src/layouts/CatalogueJur.tsx index b3e9986..018ebed 100644 --- a/src/layouts/CatalogueJur.tsx +++ b/src/layouts/CatalogueJur.tsx @@ -1,7 +1,32 @@ +import { Button, Space } from "antd"; import PageTitle from "../components/PageTitle"; import { CatalogueJurTable } from "../widgets/CatalogueJurTable/CatalogueJurTable"; +import { PlusOutlined } from "@ant-design/icons"; +import { useState } from "react"; +import { useAppDispatch, useAppSelector } from "../store/store"; +import { CatalogueJurForm } from "../widgets/CatalogueJurForm/CatalogueJurForm"; +import { getCatalogueJurThunk } from "../store/slices/catalogueJurSlice/thunks"; +import { CatalogueJurFormProps } from "../types/catalogueJur/catalogueJur"; +import { createCatalogueJur } from "../services/api/directories/catalogue_jur"; export function CatalogueJur() { + const dispatch = useAppDispatch(); + const isGettingArchive = useAppSelector( + (state) => state.catalogue_jur.isGettingArchive, + ); + + const [createFormOpen, setCreateFormOpen] = useState(false); + + async function createJurHandler(values: CatalogueJurFormProps) { + try { + await createCatalogueJur(values); + dispatch( + getCatalogueJurThunk({ closed: isGettingArchive, outside_group: true }), + ); + setCreateFormOpen(false); + } catch {} + } + return (
- + + + +
+ {createFormOpen && ( + { + setCreateFormOpen(false); + }} + onOk={(values) => { + createJurHandler(values); + }} + /> + )}
); } diff --git a/src/services/api/directories/catalogue_jur.ts b/src/services/api/directories/catalogue_jur.ts index 57b23e6..ab72517 100644 --- a/src/services/api/directories/catalogue_jur.ts +++ b/src/services/api/directories/catalogue_jur.ts @@ -2,10 +2,9 @@ import { api } from "../../../api/client"; import { GetCatalogueJurPropsI, } from "../../../store/slices/catalogueJurSlice/types"; -import { ICatalogueJur } from "../../../types/catalogueJur/catalogueJur"; +import { CatalogueJurFormProps, ICatalogueJur, MoveCatalogueJurProps, WithdrawCatalogueJurProps } from "../../../types/catalogueJur/catalogueJur"; export async function fetchCatalogueJur(params: GetCatalogueJurPropsI) { - // #TODO поменять на outside_group=true const res = await api.get( "/directories/legal-entities", params, @@ -22,3 +21,40 @@ export async function fetchOneCatalogueJur( ); return res; } + + +export async function moveCatalogueJur( + entityId: string, + body: MoveCatalogueJurProps, +): Promise { + return api.post( + `/directories/legal-entities/${entityId}/move`, + body, + ); +} +export async function withdrawCatalogueJur( + entityId: string, + body: WithdrawCatalogueJurProps, +): Promise { + return api.post( + `/directories/legal-entities/${entityId}/withdraw`, + body, + ); +} +export async function createCatalogueJur( + body: CatalogueJurFormProps, +): Promise { + return api.post( + `/directories/legal-entities`, + body, + ); +} +export async function editCatalogueJur( + entityId: string, + body: CatalogueJurFormProps, +): Promise { + return api.patch( + `/directories/legal-entities/${entityId}`, + body, + ); +} \ No newline at end of file diff --git a/src/store/slices/catalogueJurSlice/catalogueJurSlice.ts b/src/store/slices/catalogueJurSlice/catalogueJurSlice.ts index 262ccb4..24bce55 100644 --- a/src/store/slices/catalogueJurSlice/catalogueJurSlice.ts +++ b/src/store/slices/catalogueJurSlice/catalogueJurSlice.ts @@ -1,20 +1,23 @@ -import { createAsyncThunk, createSlice } from "@reduxjs/toolkit"; -import { useSelector } from "react-redux"; -import { Config } from "../../../conf/config"; -import {CatalogueJurSliceType } from "./types"; +import { createSlice, PayloadAction } from "@reduxjs/toolkit"; +import { CatalogueJurSliceType } from "./types"; import { getCatalogueJurThunk } from "./thunks"; -const initialState:CatalogueJurSliceType = { +const initialState: CatalogueJurSliceType = { raw_rows: [], total_groups: 0, loading: false, error: null, + isGettingArchive: false, }; const catalogueJurSlice = createSlice({ name: "catalogue_jur", initialState, - reducers: {}, + reducers: { + setIsGettingArchive(state, action: PayloadAction) { + state.isGettingArchive = action.payload; + }, + }, extraReducers: (builder) => { builder .addCase(getCatalogueJurThunk.pending, (state, _) => { @@ -32,5 +35,5 @@ const catalogueJurSlice = createSlice({ }); }, }); - +export const { setIsGettingArchive } = catalogueJurSlice.actions; export default catalogueJurSlice.reducer; diff --git a/src/store/slices/catalogueJurSlice/types.ts b/src/store/slices/catalogueJurSlice/types.ts index b19fb4c..2010c66 100644 --- a/src/store/slices/catalogueJurSlice/types.ts +++ b/src/store/slices/catalogueJurSlice/types.ts @@ -5,6 +5,7 @@ export interface CatalogueJurSliceType{ raw_rows: ICatalogueJur[]; loading: boolean; error: string | null; + isGettingArchive:boolean } diff --git a/src/types/catalogueJur/catalogueJur.ts b/src/types/catalogueJur/catalogueJur.ts index ae39d83..bbd6840 100644 --- a/src/types/catalogueJur/catalogueJur.ts +++ b/src/types/catalogueJur/catalogueJur.ts @@ -1,13 +1,13 @@ export interface ICatalogueJur { id: string; inn: string; - kpp: string | null; - crm_id: string | null; - entity_type: string; + kpp?: string; + crm_id?: string; + entity_type: "ЮЛ" | "ИП"; name: string; - company_group_id: string | null; + company_group_id?: string; company_group_name: string | null; - regional_office_id: string | null; + regional_office_id?: string; close_date: Date; valid_from: Date; created_at: Date; @@ -15,10 +15,38 @@ export interface ICatalogueJur { outside_group: boolean; closed: boolean | string; memberships?: unknown[]; - aliases?: unknown[]; + aliases?: JurAlliase[]; regional_office: { id: string; name: string; is_head_office: boolean; }; } + +export type JurAlliase = { + alias: string; + created_at: Date; + id: string; + normalized_alias: string; +}; + +export type MoveCatalogueJurProps = { + company_group_id: string; + effective_date: string; +}; +export type WithdrawCatalogueJurProps = { + event: "CLOSE" | "REMOVE_FROM_GROUP"; + effective_date: string; + comment: string; +}; + +export type CatalogueJurFormProps = { + inn?: string; + kpp?: string; + crm_id: string; + entity_type: "ЮЛ" | "ИП"; + name: string; + aliases?: string[] | {value:string, label:string}[]; + company_group_id?: string; + regional_office_id?: string; +}; diff --git a/src/widgets/CatalogueJurForm/CatalogueJurForm.tsx b/src/widgets/CatalogueJurForm/CatalogueJurForm.tsx new file mode 100644 index 0000000..41ff66a --- /dev/null +++ b/src/widgets/CatalogueJurForm/CatalogueJurForm.tsx @@ -0,0 +1,217 @@ +import React, { useCallback, useEffect, useState } from "react"; +import { Modal, Form, Input, Select, Row, Col, InputNumber } from "antd"; +import { CatalogueJurFormProps } from "../../types/catalogueJur/catalogueJur"; +import { useAppDispatch, useAppSelector } from "../../store/store"; +import { getCompanyGroupsThunk } from "../../store/slices/companyGroupsSlice/thunks"; +import { api } from "../../api/client"; +import { RegionalOffice } from "../../api/types"; +import { useAsyncData } from "../Admin/hooks"; +import { fetchOneCatalogueJur } from "../../services/api/directories/catalogue_jur"; + +type Props = { + open: boolean; + onCancel: () => void; + onOk: (values: CatalogueJurFormProps) => void | Promise; + jurId?: string; +}; + +export const CatalogueJurForm: React.FC = ({ + open, + onCancel, + onOk, + jurId, +}) => { + const [form] = Form.useForm(); + const dispatch = useAppDispatch(); + const loadOffices = useCallback( + () => api.get("/directories/regional-offices"), + [], + ); + const offices = useAsyncData(loadOffices); + const type = Form.useWatch("entity_type", form); + + const { raw_rows, loading } = useAppSelector((state) => state.company_groups); + const [initialDataLoading, setInitialDataLoading] = useState(false); + + async function getInitialData() { + setInitialDataLoading(true); + if (jurId) { + const data = await fetchOneCatalogueJur(jurId); + form.setFieldsValue({ + name: data?.name, + company_group_id: data?.company_group_id, + aliases: data?.aliases?.map((aliase) => aliase.alias), + crm_id: data?.crm_id, + entity_type: data?.entity_type, + inn: data.inn, + kpp: data?.kpp, + regional_office_id: data?.regional_office_id, + }); + } + setInitialDataLoading(false); + } + + const handleOk = async () => { + try { + const values = await form.validateFields(); + await onOk({ + ...values, + kpp: type === "ИП" ? undefined : values.kpp?.toString(), + inn: jurId ? undefined : values?.inn?.toString(), + company_group_id: jurId ? undefined : values.company_group_id, + }); + } catch { + return; + } + }; + + const handleCancel = () => { + form.resetFields(); + onCancel(); + }; + + useEffect(() => { + if (open && raw_rows.length === 0 && !loading) { + dispatch(getCompanyGroupsThunk()); + } + }, [open, raw_rows.length, loading, dispatch]); + + useEffect(() => { + if (!!jurId) { + getInitialData(); + } + }, [open]); + return ( + +
+ + + + + + + + + + + + + + + + + + + + + + + ({ value: g.id, label: g.name }))} + showSearch + optionFilterProp="label" + notFoundContent={loading ? "Загрузка" : "Нет вариантов"} + /> + + + + + + + +