accepted items added

This commit is contained in:
Samandar Turg'unboev
2025-06-24 09:53:03 +05:00
parent 11faf4a2c9
commit 5cad79b822
4 changed files with 103 additions and 123 deletions

View File

@@ -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>

View File

@@ -29,5 +29,5 @@ export type UpdateProductBodyType = {
nameRu: string; nameRu: string;
amount: number; amount: number;
weight: number; weight: number;
acceptedNumber: number; acceptedNumber: number | null;
}; };

View File

@@ -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>
); );
}, },
}, },

View File

@@ -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,
}, },
}); });