feat: income

This commit is contained in:
2024-12-12 20:23:38 +04:00
parent d5598a10b8
commit 38597b8f16
48 changed files with 627 additions and 438 deletions

View File

@@ -1,23 +0,0 @@
import { FC } from "react";
import useExpenseTagsList from "../../../AdminPage/hooks/useExpenseTagsList.tsx";
import { ExpenseTagSchema } from "../../../../client";
import ObjectSelect, { ObjectSelectProps } from "../../../../components/ObjectSelect/ObjectSelect.tsx";
type Props = Omit<
ObjectSelectProps<ExpenseTagSchema | null>,
"data" | "getValueFn" | "getLabelFn"
>;
const ExpenseTagSelect: FC<Props> = props => {
const { objects: tags } = useExpenseTagsList();
return (
<ObjectSelect
data={tags}
getLabelFn={(tag: ExpenseTagSchema) => tag.name}
getValueFn={(tag: ExpenseTagSchema) => tag.id.toString()}
clearable
{...props}
onClear={() => props.onChange(null)}
/>
);
};
export default ExpenseTagSelect;

View File

@@ -0,0 +1,28 @@
import { FC } from "react";
import { TransactionTagSchema } from "../../../../client";
import ObjectSelect, { ObjectSelectProps } from "../../../../components/ObjectSelect/ObjectSelect.tsx";
import useAllTransactionTagsList from "../../../AdminPage/hooks/useAllTransactionTagsList.tsx";
type IsIncome = {
isIncome: boolean;
}
type Props = Omit<
ObjectSelectProps<TransactionTagSchema | null>,
"data" | "getValueFn" | "getLabelFn"
> & IsIncome;
const TransactionTagSelect: FC<Props> = props => {
let { objects: tags } = useAllTransactionTagsList();
tags = tags.filter(tag => tag.isIncome === props.isIncome);
return (
<ObjectSelect
data={tags}
getLabelFn={(tag: TransactionTagSchema) => tag.name}
getValueFn={(tag: TransactionTagSchema) => tag.id.toString()}
clearable
{...props}
onClear={() => props.onChange(null)}
/>
);
};
export default TransactionTagSelect;

View File

@@ -1,7 +1,7 @@
import { DatePickerInput, DatePickerInputProps } from "@mantine/dates";
import { Divider, Stack, Text } from "@mantine/core";
import ClientSelectNew from "../../../../../../components/Selects/ClientSelectNew/ClientSelectNew.tsx";
import { BaseMarketplaceSchema, ClientSchema, ExpenseTagSchema, UserSchema } from "../../../../../../client";
import { BaseMarketplaceSchema, ClientSchema, TransactionTagSchema, UserSchema } from "../../../../../../client";
import { ObjectSelectProps } from "../../../../../../components/ObjectSelect/ObjectSelect.tsx";
import BaseMarketplaceSelect
from "../../../../../../components/Selects/BaseMarketplaceSelect/BaseMarketplaceSelect.tsx";
@@ -9,35 +9,34 @@ import DealStatusSelect from "../../../../../DealsPage/components/DealStatusSele
import { DealStatusType } from "../../../../../../shared/enums/DealStatus.ts";
import { ProfitTableSegmentedControl } from "../ProfitTableSegmentedControl/ProfitTableSegmentedControl.tsx";
import ManagerSelect from "../../../../../../components/ManagerSelect/ManagerSelect.tsx";
import ExpenseTagSelect from "../../../../components/ExpenseTagSelect/ExpenseTagSelect.tsx";
import TransactionTagSelect from "../../../../components/ExpenseTagSelect/TransactionTagSelect.tsx";
type SelectProps<T> = Omit<
ObjectSelectProps<T>,
"data" | "getValueFn" | "getLabelFn"
>;
type FiltersProps = {
datePickerProps?: DatePickerInputProps<"range">;
clientSelectProps?: Omit<ObjectSelectProps<ClientSchema>, "data">;
onClientClear?: () => void;
baseMarketplaceSelectProps?: Omit<
ObjectSelectProps<BaseMarketplaceSchema>,
"data" | "getValueFn" | "getLabelFn"
>;
baseMarketplaceSelectProps?: SelectProps<BaseMarketplaceSchema>;
onBaseMarketplaceClear?: () => void;
dealStatusSelectProps?: Omit<ObjectSelectProps<DealStatusType>, "data">;
onDealStatusClear?: () => void;
managerSelectProps?: Omit<
ObjectSelectProps<UserSchema | null>,
"data" | "getValueFn" | "getLabelFn"
>;
managerSelectProps?: SelectProps<UserSchema | null | undefined>;
onManagerClear?: () => void;
tagSelectProps?: Omit<
ObjectSelectProps<ExpenseTagSchema | null>,
"data" | "getValueFn" | "getLabelFn"
>;
onTagClear?: () => void;
expenseTagSelectProps?: SelectProps<TransactionTagSchema | null>;
onExpenseTagClear?: () => void;
incomeTagSelectProps?: SelectProps<TransactionTagSchema | null>;
onIncomeTagClear?: () => void;
groupTableByProps?: {
value: string,
@@ -46,20 +45,24 @@ type FiltersProps = {
}
export const Filters = (props: FiltersProps) => {
const {
datePickerProps,
clientSelectProps,
onClientClear,
baseMarketplaceSelectProps,
onBaseMarketplaceClear,
dealStatusSelectProps,
onDealStatusClear,
managerSelectProps,
onManagerClear,
tagSelectProps,
onTagClear,
groupTableByProps,
} = props;
const getTransactionTagsSelect = (isIncome: boolean) => {
const selectProps = isIncome ? props.incomeTagSelectProps : props.expenseTagSelectProps;
if (!selectProps) return;
const onClear = isIncome ? props.onIncomeTagClear : props.onExpenseTagClear;
const label = "Фильтры для " + (isIncome ? "доходов:" : "расходов:");
return (
<>
<Divider />
<Text>{label}</Text>
<TransactionTagSelect
{...selectProps}
onClear={onClear}
placeholder={"Выберите тег"}
isIncome={isIncome}
/>
</>
)
}
return (
<Stack mb={"lg"}>
@@ -67,64 +70,55 @@ export const Filters = (props: FiltersProps) => {
<Text>
Фильтры для выручки и прибыли:
</Text>
{datePickerProps &&
{props.datePickerProps &&
<DatePickerInput
{...datePickerProps}
{...props.datePickerProps}
type="range"
placeholder="Выберите даты"
maxDate={new Date()}
valueFormat={"DD.MM.YYYY"}
/>
}
{dealStatusSelectProps &&
{props.dealStatusSelectProps &&
<DealStatusSelect
{...dealStatusSelectProps}
onClear={onDealStatusClear}
{...props.dealStatusSelectProps}
onClear={props.onDealStatusClear}
clearable
placeholder={"Выберите статус"}
/>
}
{clientSelectProps &&
{props.clientSelectProps &&
<ClientSelectNew
{...clientSelectProps}
onClear={onClientClear}
{...props.clientSelectProps}
onClear={props.onClientClear}
clearable
searchable
placeholder={"Выберите клиента"}
/>
}
{baseMarketplaceSelectProps &&
{props.baseMarketplaceSelectProps &&
<BaseMarketplaceSelect
{...baseMarketplaceSelectProps}
onClear={onBaseMarketplaceClear}
{...props.baseMarketplaceSelectProps}
onClear={props.onBaseMarketplaceClear}
clearable
placeholder={"Выберите маркетплейс"}
/>
}
{managerSelectProps &&
{props.managerSelectProps &&
<ManagerSelect
{...managerSelectProps}
onClear={onManagerClear}
{...props.managerSelectProps}
onClear={props.onManagerClear}
placeholder={"Выберите менеджера"}
/>
}
{tagSelectProps &&
<>
<Divider />
<Text>Фильтры для расходов:</Text>
<ExpenseTagSelect
{...tagSelectProps}
onClear={onTagClear}
placeholder={"Выберите тег"}
/>
</>
}
{groupTableByProps &&
{getTransactionTagsSelect(false)}
{getTransactionTagsSelect(true)}
{props.groupTableByProps &&
<>
<Divider />
<Text>Группировка таблицы:</Text>
<ProfitTableSegmentedControl
{...groupTableByProps}
{...props.groupTableByProps}
orientation={"vertical"}
size={"md"}
w={"100%"}

View File

@@ -29,7 +29,8 @@ const useProfitTabContextState = () => {
marketplace: null,
dealStatus: defaultDealStatus,
manager: null,
tag: null,
expenseTag: null,
incomeTag: null,
},
});
const [isChartLoading, setIsChartLoading] = useState(false);
@@ -49,7 +50,8 @@ const useProfitTabContextState = () => {
baseMarketplaceKey: form.values.marketplace?.key ?? "all",
dealStatusId: form.values.dealStatus?.id ?? -1,
managerId: form.values.manager?.id ?? -1,
tagId: form.values.tag?.id ?? -1,
expenseTagId: form.values.expenseTag?.id ?? -1,
incomeTagId: form.values.incomeTag?.id ?? -1,
};
};

View File

@@ -44,8 +44,10 @@ export const ProfitFiltersModal = ({ form }: Props) => {
onDealStatusClear={() => form.setFieldValue("dealStatus", null)}
managerSelectProps={form.getInputProps("manager")}
onManagerClear={() => form.setFieldValue("manager", null)}
tagSelectProps={form.getInputProps("tag")}
onTagClear={() => form.setFieldValue("tag", null)}
expenseTagSelectProps={form.getInputProps("expenseTag")}
onExpenseTagClear={() => form.setFieldValue("expenseTag", null)}
incomeTagSelectProps={form.getInputProps("incomeTag")}
onIncomeTagClear={() => form.setFieldValue("incomeTag", null)}
/>
</Modal>
</>

View File

@@ -1,7 +1,7 @@
import {
GroupStatisticsTable,
} from "../tabs/ProfitTab/components/ProfitTableSegmentedControl/ProfitTableSegmentedControl.tsx";
import { BaseMarketplaceSchema, ClientSchema, ExpenseTagSchema, UserSchema } from "../../../client";
import { BaseMarketplaceSchema, ClientSchema, TransactionTagSchema, UserSchema } from "../../../client";
import { DealStatusType } from "../../../shared/enums/DealStatus.ts";
export interface FormFilters {
@@ -11,5 +11,6 @@ export interface FormFilters {
marketplace: BaseMarketplaceSchema | null;
dealStatus: DealStatusType | null;
manager: UserSchema | null;
tag: ExpenseTagSchema | null;
expenseTag: TransactionTagSchema | null;
incomeTag: TransactionTagSchema | null;
}