feat: expenses in statistics

This commit is contained in:
2024-11-24 19:23:33 +04:00
parent 2007ecd2f2
commit e3146832a5
5 changed files with 49 additions and 20 deletions

View File

@@ -6,6 +6,7 @@ export type ProfitChartDataItem = {
date: string; date: string;
revenue: number; revenue: number;
profit: number; profit: number;
expenses: number;
dealsCount: number; dealsCount: number;
}; };

View File

@@ -6,6 +6,7 @@ export type ProfitTableDataItem = {
groupedValue: (string | number); groupedValue: (string | number);
revenue: number; revenue: number;
profit: number; profit: number;
expenses?: (number | null);
dealsCount: number; dealsCount: number;
}; };

View File

@@ -26,6 +26,7 @@ export const ProfitChart = () => {
[ [
{ name: "profit", label: "Прибыль", color: "indigo.6" }, { name: "profit", label: "Прибыль", color: "indigo.6" },
{ name: "revenue", label: "Выручка", color: "teal.6" }, { name: "revenue", label: "Выручка", color: "teal.6" },
{ name: "expenses", label: "Расходы", color: "red.6" },
], ],
[ [
{ name: "dealsCount", label: "Количество сделок", color: "indigo.6" }, { name: "dealsCount", label: "Количество сделок", color: "indigo.6" },
@@ -34,6 +35,8 @@ export const ProfitChart = () => {
const units = ["₽", "шт"]; const units = ["₽", "шт"];
const chartSizes = ["42vh", "28vh"];
return ( return (
<div className={styles["profit-chart-container"]}> <div className={styles["profit-chart-container"]}>
<Total profitData={profitData} /> <Total profitData={profitData} />
@@ -42,13 +45,13 @@ export const ProfitChart = () => {
form={form} form={form}
/> />
<Skeleton visible={isLoading}> <Skeleton visible={isLoading}>
<Stack gap={"xl"}> <Stack gap="20px">
{getChartsSeries.map((series, idx) => { {getChartsSeries.map((series, idx) => {
return ( return (
<AreaChart <AreaChart
my={"sm"} my={"sm"}
w={"98%"} w={"98%"}
h={"34vh"} h={chartSizes[idx]}
data={formattedProfitData} data={formattedProfitData}
dataKey="date" dataKey="date"
unit={units[idx]} unit={units[idx]}

View File

@@ -19,6 +19,28 @@ export const useProfitTableColumns = ({ groupTableBy }: Props) => {
[GroupStatisticsTable.BY_MANAGERS]: "Менеджер", [GroupStatisticsTable.BY_MANAGERS]: "Менеджер",
}; };
const getConditionalColumns = (): MRT_ColumnDef<ProfitTableDataItem>[] => {
if (groupTableBy === GroupStatisticsTable.BY_DATES) {
return [
{
accessorKey: "revenue",
header: "Выручка",
Cell: ({ row }) =>
row.original.revenue.toLocaleString("ru-RU") + "₽",
size: 50,
},
{
accessorKey: "expenses",
header: "Расходы",
Cell: ({ row }) =>
row.original.expenses?.toLocaleString("ru-RU") + "₽",
size: 50,
}
] as MRT_ColumnDef<ProfitTableDataItem>[];
}
return [];
};
return useMemo<MRT_ColumnDef<ProfitTableDataItem>[]>( return useMemo<MRT_ColumnDef<ProfitTableDataItem>[]>(
() => [ () => [
{ {
@@ -35,13 +57,14 @@ export const useProfitTableColumns = ({ groupTableBy }: Props) => {
} }
return row.original.groupedValue; return row.original.groupedValue;
}, },
size: 60, size: groupTableBy === GroupStatisticsTable.BY_DATES ? 40 : 80,
}, },
{ {
accessorKey: "dealsCount", accessorKey: "dealsCount",
header: "Кол-во", header: "Кол-во",
size: 40, size: 40,
}, },
...getConditionalColumns(),
{ {
accessorKey: "profit", accessorKey: "profit",
header: "Прибыль", header: "Прибыль",
@@ -49,13 +72,6 @@ export const useProfitTableColumns = ({ groupTableBy }: Props) => {
row.original.profit.toLocaleString("ru-RU") + "₽", row.original.profit.toLocaleString("ru-RU") + "₽",
size: 50, size: 50,
}, },
{
accessorKey: "revenue",
header: "Выручка",
Cell: ({ row }) =>
row.original.revenue.toLocaleString("ru-RU") + "₽",
size: 50,
},
], ],
[groupTableBy], [groupTableBy],
); );

View File

@@ -7,14 +7,18 @@ type Props = {
}; };
export const Total = ({ profitData }: Props) => { export const Total = ({ profitData }: Props) => {
const totalProfit = profitData.reduce(
(sum, dataItem) => dataItem.profit + sum,
0,
);
const totalRevenue = profitData.reduce( const totalRevenue = profitData.reduce(
(sum, dataItem) => dataItem.revenue + sum, (sum, dataItem) => dataItem.revenue + sum,
0, 0,
); );
const totalExpense = profitData.reduce(
(sum, dataItem) => dataItem.expenses + sum,
0,
);
const totalProfit = profitData.reduce(
(sum, dataItem) => dataItem.profit + sum,
0,
);
const totalCount = profitData.reduce( const totalCount = profitData.reduce(
(sum, dataItem) => dataItem.dealsCount + sum, (sum, dataItem) => dataItem.dealsCount + sum,
0, 0,
@@ -23,15 +27,19 @@ export const Total = ({ profitData }: Props) => {
return ( return (
<PageBlock style={{ padding: "25px", height: "7vh", flexGrow: 0 }}> <PageBlock style={{ padding: "25px", height: "7vh", flexGrow: 0 }}>
<Group gap={2} justify={"space-between"}> <Group gap={2} justify={"space-between"}>
<Center w={"30%"}> <Center w={"24%"}>
<Text>Прибыль: {new Intl.NumberFormat("ru-RU").format(totalProfit)} </Text>
</Center>
<Divider size={"md"} orientation="vertical" />
<Center w={"30%"}>
<Text>Выручка: {new Intl.NumberFormat("ru-RU").format(totalRevenue)} </Text> <Text>Выручка: {new Intl.NumberFormat("ru-RU").format(totalRevenue)} </Text>
</Center> </Center>
<Divider size={"md"} orientation="vertical" /> <Divider size={"md"} orientation="vertical" />
<Center w={"30%"}> <Center w={"24%"}>
<Text>Расходы: {new Intl.NumberFormat("ru-RU").format(totalExpense)} </Text>
</Center>
<Divider size={"md"} orientation="vertical" />
<Center w={"24%"}>
<Text>Прибыль: {new Intl.NumberFormat("ru-RU").format(totalProfit)} </Text>
</Center>
<Divider size={"md"} orientation="vertical" />
<Center w={"24%"}>
<Text>Сделок: {new Intl.NumberFormat("ru-RU").format(totalCount)} шт</Text> <Text>Сделок: {new Intl.NumberFormat("ru-RU").format(totalCount)} шт</Text>
</Center> </Center>
</Group> </Group>