accepted items added
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
import Loader from '@/components/common/Loader';
|
import Loader from '@/components/common/Loader';
|
||||||
import { Scrollbar } from '@/components/common/Scrollbar';
|
import { Scrollbar } from '@/components/common/Scrollbar';
|
||||||
import { box_requests } from '@/data/box/box.requests';
|
import { box_requests } from '@/data/box/box.requests';
|
||||||
import useRequest from '@/hooks/useRequest';
|
|
||||||
import { Box, styled, SxProps, Table, TableBody, TableCell, TableHead, TableRow, Theme } from '@mui/material';
|
import { Box, styled, SxProps, Table, TableBody, TableCell, TableHead, TableRow, Theme } from '@mui/material';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
@@ -50,6 +51,7 @@ const StyledTable = styled(Table)`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledTableRow = styled(TableRow)``;
|
const StyledTableRow = styled(TableRow)``;
|
||||||
const StyledTableCell = styled(TableCell)`
|
const StyledTableCell = styled(TableCell)`
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
@@ -64,10 +66,47 @@ type Props<Data> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const MyTable = <Data extends { id: number | string }>(props: Props<Data>) => {
|
const MyTable = <Data extends { id: number | string }>(props: Props<Data>) => {
|
||||||
const { columns, data, loading, onClickRow, color } = props;
|
const { columns, data, loading, onClickRow } = props;
|
||||||
|
|
||||||
const isEmpty = !data?.length && !loading;
|
const isEmpty = !data?.length && !loading;
|
||||||
|
|
||||||
|
const [boxStatuses, setBoxStatuses] = React.useState<Record<string, boolean>>({});
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
const fetchBoxStatuses = async () => {
|
||||||
|
const statuses: Record<string, boolean> = {};
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
data.map(async row => {
|
||||||
|
try {
|
||||||
|
const res = await box_requests.find({ packetId: row.id });
|
||||||
|
const boxData = res.data.data;
|
||||||
|
|
||||||
|
const total = boxData.items.reduce(
|
||||||
|
(acc: { totalAmount: number; totalAccepted: number }, item: any) => {
|
||||||
|
acc.totalAmount += +item.amount || 0;
|
||||||
|
acc.totalAccepted += +item.acceptedNumber || 0;
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{ totalAmount: 0, totalAccepted: 0 }
|
||||||
|
);
|
||||||
|
|
||||||
|
statuses[row.id] = total.totalAmount === total.totalAccepted;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching box status:', error);
|
||||||
|
statuses[row.id] = false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
setBoxStatuses(statuses);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!loading && data.length > 0) {
|
||||||
|
fetchBoxStatuses();
|
||||||
|
}
|
||||||
|
}, [data, loading]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Scrollbar>
|
<Scrollbar>
|
||||||
@@ -76,10 +115,9 @@ const MyTable = <Data extends { id: number | string }>(props: Props<Data>) => {
|
|||||||
<StyledTableRow>
|
<StyledTableRow>
|
||||||
{columns.map((column, index) => (
|
{columns.map((column, index) => (
|
||||||
<StyledTableCell
|
<StyledTableCell
|
||||||
// @ts-expect-error
|
key={String(column.dataKey) + index}
|
||||||
key={column.dataKey + index}
|
|
||||||
variant='head'
|
variant='head'
|
||||||
align={column.numeric || false ? 'right' : 'left'}
|
align={column.numeric ? 'right' : 'left'}
|
||||||
sx={{
|
sx={{
|
||||||
backgroundColor: 'background.paper',
|
backgroundColor: 'background.paper',
|
||||||
width: column.width,
|
width: column.width,
|
||||||
@@ -93,63 +131,18 @@ const MyTable = <Data extends { id: number | string }>(props: Props<Data>) => {
|
|||||||
</TableHead>
|
</TableHead>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{isEmpty ? (
|
{isEmpty ? (
|
||||||
'Empty'
|
<StyledTableRow>
|
||||||
|
<StyledTableCell colSpan={columns.length}>Empty</StyledTableCell>
|
||||||
|
</StyledTableRow>
|
||||||
) : loading ? (
|
) : loading ? (
|
||||||
<StyledTableCell colSpan={columns.length}>
|
<StyledTableRow>
|
||||||
<Loader p={4} size={96} />
|
<StyledTableCell colSpan={columns.length}>
|
||||||
</StyledTableCell>
|
<Loader p={4} size={96} />
|
||||||
|
</StyledTableCell>
|
||||||
|
</StyledTableRow>
|
||||||
) : (
|
) : (
|
||||||
data.map((row: any, rowIndex) => {
|
data.map((row: any, rowIndex) => {
|
||||||
let status = undefined;
|
const status = boxStatuses[row.id];
|
||||||
const getOneBox = useRequest(
|
|
||||||
() => {
|
|
||||||
return box_requests.find({ packetId: row.id });
|
|
||||||
},
|
|
||||||
{
|
|
||||||
selectData(data) {
|
|
||||||
const boxData = data.data.data;
|
|
||||||
|
|
||||||
return {
|
|
||||||
products_list: [
|
|
||||||
...boxData.items.map(item => {
|
|
||||||
let name = item.name;
|
|
||||||
let nameRu = item.nameRu;
|
|
||||||
|
|
||||||
return {
|
|
||||||
id: item.id,
|
|
||||||
price: item.price,
|
|
||||||
|
|
||||||
cargoId: item.cargoId,
|
|
||||||
trekId: item.trekId,
|
|
||||||
name: name,
|
|
||||||
acceptedNumber: item.acceptedNumber,
|
|
||||||
nameRu: nameRu,
|
|
||||||
amount: +item.amount,
|
|
||||||
weight: +item.weight,
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
};
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
{
|
|
||||||
(() => {
|
|
||||||
const total = getOneBox.data?.products_list.reduce(
|
|
||||||
(acc, product) => {
|
|
||||||
console.log(product, 'totalAccepted');
|
|
||||||
acc.totalAmount += +product.amount || 0;
|
|
||||||
acc.totalAccepted += +product.acceptedNumber || 0;
|
|
||||||
return acc;
|
|
||||||
},
|
|
||||||
{ totalAmount: 0, totalAccepted: 0 }
|
|
||||||
);
|
|
||||||
|
|
||||||
status = total?.totalAmount === total?.totalAccepted;
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(row, 'clent');
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledTableRow
|
<StyledTableRow
|
||||||
@@ -165,21 +158,18 @@ const MyTable = <Data extends { id: number | string }>(props: Props<Data>) => {
|
|||||||
}
|
}
|
||||||
: {}),
|
: {}),
|
||||||
}}
|
}}
|
||||||
onClick={() => {
|
onClick={() => onClickRow?.(row)}
|
||||||
onClickRow?.(row);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{columns.map((column, index) => (
|
{columns.map((column, index) => (
|
||||||
<StyledTableCell
|
<StyledTableCell
|
||||||
// @ts-expect-error
|
key={String(column.dataKey) + index}
|
||||||
key={column.dataKey + index}
|
align={column.numeric ? 'right' : 'left'}
|
||||||
align={column.numeric || false ? 'right' : 'left'}
|
|
||||||
sx={{
|
sx={{
|
||||||
...column.getSxStyles?.(row),
|
...column.getSxStyles?.(row),
|
||||||
width: column.width,
|
width: column.width,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{column.renderCell ? column.renderCell(row, rowIndex) : row[column.dataKey]}
|
{column.renderCell ? column.renderCell(row, rowIndex) : row[column.dataKey as keyof Data]}
|
||||||
</StyledTableCell>
|
</StyledTableCell>
|
||||||
))}
|
))}
|
||||||
</StyledTableRow>
|
</StyledTableRow>
|
||||||
|
|||||||
@@ -29,5 +29,5 @@ export type UpdateProductBodyType = {
|
|||||||
nameRu: string;
|
nameRu: string;
|
||||||
amount: number;
|
amount: number;
|
||||||
weight: number;
|
weight: number;
|
||||||
acceptedNumber: number;
|
acceptedNumber: number | null;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ const DashboardBoxesPage = (props: Props) => {
|
|||||||
const [deleteIds, setDeleteIds] = useState<number[]>([]);
|
const [deleteIds, setDeleteIds] = useState<number[]>([]);
|
||||||
const [downloadIds, setDownloadIds] = useState<number[]>([]);
|
const [downloadIds, setDownloadIds] = useState<number[]>([]);
|
||||||
const [changeStatusIds, setChangeStatusIds] = useState<number[]>([]);
|
const [changeStatusIds, setChangeStatusIds] = useState<number[]>([]);
|
||||||
|
const [boxAmounts, setBoxAmounts] = useState<Record<number, { totalAmount: number; totalAccepted: number }>>({});
|
||||||
|
|
||||||
const boxStatusOptions = useMemo(() => {
|
const boxStatusOptions = useMemo(() => {
|
||||||
const p = ['READY_TO_INVOICE'] as BoxStatus[];
|
const p = ['READY_TO_INVOICE'] as BoxStatus[];
|
||||||
@@ -192,6 +193,40 @@ const DashboardBoxesPage = (props: Props) => {
|
|||||||
return () => clearTimeout(timeoutId);
|
return () => clearTimeout(timeoutId);
|
||||||
}, [keyword]);
|
}, [keyword]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchAmounts = async () => {
|
||||||
|
const result: Record<number, { totalAmount: number; totalAccepted: number }> = {};
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
list.map(async box => {
|
||||||
|
try {
|
||||||
|
const res = await box_requests.find({ packetId: box.id });
|
||||||
|
const boxData = res.data.data;
|
||||||
|
|
||||||
|
const total = boxData.items.reduce(
|
||||||
|
(acc: { totalAmount: number; totalAccepted: number }, item: any) => {
|
||||||
|
acc.totalAmount += +item.amount || 0;
|
||||||
|
acc.totalAccepted += +item.acceptedNumber || 0;
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{ totalAmount: 0, totalAccepted: 0 }
|
||||||
|
);
|
||||||
|
|
||||||
|
result[box.id] = total;
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`Failed to fetch box ${box.id}`, e);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
setBoxAmounts(result);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (list.length > 0 && !loading) {
|
||||||
|
fetchAmounts();
|
||||||
|
}
|
||||||
|
}, [list, loading]);
|
||||||
|
|
||||||
// No, PartyName, PacketName, PartyTozaOg'irlik, CountOfItems, WeightOfItems, CargoID, PassportNameFamily - PacketStatusForInvoice
|
// No, PartyName, PacketName, PartyTozaOg'irlik, CountOfItems, WeightOfItems, CargoID, PassportNameFamily - PacketStatusForInvoice
|
||||||
const columns: ColumnData<IBox>[] = [
|
const columns: ColumnData<IBox>[] = [
|
||||||
{
|
{
|
||||||
@@ -233,59 +268,12 @@ const DashboardBoxesPage = (props: Props) => {
|
|||||||
label: t('count_of_items'),
|
label: t('count_of_items'),
|
||||||
width: 120,
|
width: 120,
|
||||||
renderCell: data => {
|
renderCell: data => {
|
||||||
const getOneBox = useRequest(
|
const total = boxAmounts[data.id];
|
||||||
() => {
|
if (!total) return <Typography>...</Typography>;
|
||||||
return box_requests.find({ packetId: data.id });
|
|
||||||
},
|
|
||||||
{
|
|
||||||
selectData(data) {
|
|
||||||
const boxData = data.data.data;
|
|
||||||
|
|
||||||
return {
|
|
||||||
products_list: [
|
|
||||||
...boxData.items.map(item => {
|
|
||||||
let name = item.name;
|
|
||||||
let nameRu = item.nameRu;
|
|
||||||
|
|
||||||
return {
|
|
||||||
id: item.id,
|
|
||||||
price: item.price,
|
|
||||||
|
|
||||||
cargoId: item.cargoId,
|
|
||||||
trekId: item.trekId,
|
|
||||||
name: name,
|
|
||||||
acceptedNumber: item.acceptedNumber,
|
|
||||||
nameRu: nameRu,
|
|
||||||
amount: +item.amount,
|
|
||||||
weight: +item.weight,
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
};
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<Typography>
|
||||||
{(() => {
|
{total.totalAmount} | {total.totalAccepted}
|
||||||
const total = getOneBox.data?.products_list.reduce(
|
</Typography>
|
||||||
(acc, product) => {
|
|
||||||
console.log(product, 'totalAccepted');
|
|
||||||
acc.totalAmount += +product.amount || 0;
|
|
||||||
acc.totalAccepted += +product.acceptedNumber || 0;
|
|
||||||
return acc;
|
|
||||||
},
|
|
||||||
{ totalAmount: 0, totalAccepted: 0 }
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Typography>
|
|
||||||
{total?.totalAmount} | {total?.totalAccepted}
|
|
||||||
</Typography>
|
|
||||||
);
|
|
||||||
})()}
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
import BaseButton from '@/components/ui-kit/BaseButton';
|
import BaseButton from '@/components/ui-kit/BaseButton';
|
||||||
import BaseInput from '@/components/ui-kit/BaseInput';
|
import BaseInput from '@/components/ui-kit/BaseInput';
|
||||||
import BaseModal from '@/components/ui-kit/BaseModal';
|
import BaseModal from '@/components/ui-kit/BaseModal';
|
||||||
import BaseReactSelect from '@/components/ui-kit/BaseReactSelect';
|
|
||||||
import { Product } from '@/data/item/item.mode';
|
import { Product } from '@/data/item/item.mode';
|
||||||
import { item_requests } from '@/data/item/item.requests';
|
import { item_requests } from '@/data/item/item.requests';
|
||||||
import { staff_requests } from '@/data/staff/staff.requests';
|
|
||||||
import { useMyTranslation } from '@/hooks/useMyTranslation';
|
import { useMyTranslation } from '@/hooks/useMyTranslation';
|
||||||
import { notifyUnknownError } from '@/services/notification';
|
import { notifyUnknownError } from '@/services/notification';
|
||||||
import { Box, Grid, Stack, Typography, styled } from '@mui/material';
|
import { Box, Grid, Stack, Typography, styled } from '@mui/material';
|
||||||
import React, { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Controller, useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
|
|
||||||
const StyledBox = styled(Box)`
|
const StyledBox = styled(Box)`
|
||||||
.title {
|
.title {
|
||||||
@@ -52,6 +50,8 @@ const EditItemModal = ({ onClose, open, onSuccess, item }: Props) => {
|
|||||||
name: string;
|
name: string;
|
||||||
amount: number;
|
amount: number;
|
||||||
weight: number;
|
weight: number;
|
||||||
|
acceptedNumber: number | null;
|
||||||
|
nameRu: string;
|
||||||
}>({
|
}>({
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
amount: item.amount,
|
amount: item.amount,
|
||||||
@@ -59,6 +59,8 @@ const EditItemModal = ({ onClose, open, onSuccess, item }: Props) => {
|
|||||||
name: item.name,
|
name: item.name,
|
||||||
trekId: item.trekId,
|
trekId: item.trekId,
|
||||||
weight: item.weight,
|
weight: item.weight,
|
||||||
|
acceptedNumber: item.acceptedNumber,
|
||||||
|
nameRu: item.nameRu,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user