437 lines
10 KiB
TypeScript
437 lines
10 KiB
TypeScript
import { GridColDef, GridRenderCellParams } from '@mui/x-data-grid-premium';
|
|
import Box from '@mui/material/Box';
|
|
import Typography from '@mui/material/Typography';
|
|
import Chip from '@mui/material/Chip';
|
|
import Tooltip from '@mui/material/Tooltip';
|
|
import {
|
|
formatDate,
|
|
formatDateTime,
|
|
formatCurrency,
|
|
formatNumber,
|
|
} from '../utils/orderFormatters';
|
|
import {
|
|
getStatusChipProps,
|
|
getPriorityChipProps,
|
|
} from '../utils/tableHelpers';
|
|
|
|
|
|
|
|
const CELL_FONT_SIZE = '0.75rem';
|
|
const CAPTION_FONT_SIZE = '0.6875rem';
|
|
|
|
const CHIP_STYLES = {
|
|
fontSize: CAPTION_FONT_SIZE,
|
|
height: 22,
|
|
fontWeight: 300,
|
|
} as const;
|
|
|
|
const CHIP_PRIORITY_STYLES = {
|
|
...CHIP_STYLES,
|
|
maxWidth: '100%',
|
|
'& .MuiChip-label': {
|
|
px: 1,
|
|
py: 0,
|
|
overflow: 'hidden',
|
|
textOverflow: 'ellipsis',
|
|
whiteSpace: 'nowrap',
|
|
},
|
|
} as const;
|
|
|
|
|
|
|
|
interface CellTextProps {
|
|
value: unknown;
|
|
secondary?: boolean;
|
|
fontWeight?: number;
|
|
}
|
|
|
|
|
|
const CellText = ({ value, secondary = false, fontWeight }: CellTextProps) => (
|
|
<Typography
|
|
variant="body2"
|
|
color={secondary ? 'text.secondary' : 'text.primary'}
|
|
sx={{ fontSize: CELL_FONT_SIZE, fontWeight }}
|
|
noWrap
|
|
>
|
|
{String(value ?? '-')}
|
|
</Typography>
|
|
);
|
|
|
|
interface CellNumericProps {
|
|
value: unknown;
|
|
formatter?: (val: number) => string;
|
|
secondary?: boolean;
|
|
fontWeight?: number;
|
|
}
|
|
|
|
|
|
const CellNumeric = ({
|
|
value,
|
|
formatter,
|
|
secondary = false,
|
|
fontWeight,
|
|
}: CellNumericProps) => (
|
|
<Typography
|
|
variant="body2"
|
|
color={secondary ? 'text.secondary' : 'text.primary'}
|
|
sx={{ fontSize: CELL_FONT_SIZE, fontWeight, textAlign: 'right' }}
|
|
>
|
|
{formatter ? formatter(value as number) : String(value ?? '-')}
|
|
</Typography>
|
|
);
|
|
|
|
interface CellDateProps {
|
|
value: unknown;
|
|
showTime?: boolean;
|
|
time?: string;
|
|
}
|
|
|
|
const CellDate = ({ value, showTime = false, time }: CellDateProps) => {
|
|
const dateStr = formatDate(value as string | undefined);
|
|
|
|
if (!showTime && !time) {
|
|
return (
|
|
<Typography variant="body2" sx={{ fontSize: CELL_FONT_SIZE }}>
|
|
{dateStr}
|
|
</Typography>
|
|
);
|
|
}
|
|
|
|
const timeStr = time || formatDateTime(value as string | undefined);
|
|
|
|
return (
|
|
<Box>
|
|
<Typography variant="body2" sx={{ fontSize: CELL_FONT_SIZE }}>
|
|
{dateStr}
|
|
</Typography>
|
|
{timeStr && (
|
|
<Typography
|
|
variant="caption"
|
|
color="text.secondary"
|
|
sx={{ fontSize: CAPTION_FONT_SIZE }}
|
|
>
|
|
{timeStr}
|
|
</Typography>
|
|
)}
|
|
</Box>
|
|
);
|
|
};
|
|
|
|
|
|
|
|
interface CreateOrderColumnsOptions {
|
|
storesMap?: Map<string, string>;
|
|
}
|
|
|
|
export const createOrderColumns = (
|
|
options?: CreateOrderColumnsOptions
|
|
): GridColDef[] => {
|
|
const storesMap = options?.storesMap;
|
|
|
|
return [
|
|
|
|
{
|
|
field: 'orderId',
|
|
headerName: 'Pedido',
|
|
width: 120,
|
|
minWidth: 100,
|
|
headerAlign: 'right',
|
|
align: 'right',
|
|
renderCell: (params: Readonly<GridRenderCellParams>) => (
|
|
<CellNumeric value={params.value} fontWeight={500} />
|
|
),
|
|
},
|
|
{
|
|
field: 'createDate',
|
|
headerName: 'Data',
|
|
width: 160,
|
|
minWidth: 140,
|
|
renderCell: (params: Readonly<GridRenderCellParams>) => (
|
|
<CellDate value={params.value} showTime />
|
|
),
|
|
},
|
|
|
|
|
|
{
|
|
field: 'customerName',
|
|
headerName: 'Cliente',
|
|
width: 300,
|
|
minWidth: 250,
|
|
flex: 1,
|
|
renderCell: (params: Readonly<GridRenderCellParams>) => (
|
|
<CellText value={params.value} />
|
|
),
|
|
},
|
|
{
|
|
field: 'customerId',
|
|
headerName: 'Código Cliente',
|
|
width: 120,
|
|
minWidth: 110,
|
|
headerAlign: 'right',
|
|
align: 'right',
|
|
renderCell: (params: Readonly<GridRenderCellParams>) => (
|
|
<CellNumeric value={params.value} secondary />
|
|
),
|
|
},
|
|
|
|
|
|
{
|
|
field: 'storeId',
|
|
headerName: 'Filial',
|
|
width: 200,
|
|
minWidth: 180,
|
|
renderCell: (params: Readonly<GridRenderCellParams>) => {
|
|
const storeId = String(params.value);
|
|
const storeName = storesMap?.get(storeId) || storeId;
|
|
return <CellText value={storeName} />;
|
|
},
|
|
},
|
|
{
|
|
field: 'store',
|
|
headerName: 'Supervisor',
|
|
width: 200,
|
|
minWidth: 180,
|
|
renderCell: (params: Readonly<GridRenderCellParams>) => (
|
|
<CellText value={params.value} />
|
|
),
|
|
},
|
|
|
|
|
|
{
|
|
field: 'status',
|
|
headerName: 'Situação',
|
|
width: 180,
|
|
minWidth: 160,
|
|
renderCell: (params: Readonly<GridRenderCellParams>) => {
|
|
const status = params.value as string;
|
|
const chipProps = getStatusChipProps(status);
|
|
|
|
return (
|
|
<Tooltip title={chipProps.label} arrow placement="top">
|
|
<Chip
|
|
label={chipProps.label}
|
|
color={chipProps.color}
|
|
size="small"
|
|
sx={CHIP_STYLES}
|
|
/>
|
|
</Tooltip>
|
|
);
|
|
},
|
|
},
|
|
{
|
|
field: 'orderType',
|
|
headerName: 'Tipo',
|
|
width: 140,
|
|
minWidth: 120,
|
|
renderCell: (params: Readonly<GridRenderCellParams>) => (
|
|
<CellText value={params.value} />
|
|
),
|
|
},
|
|
|
|
|
|
{
|
|
field: 'amount',
|
|
headerName: 'Valor Total',
|
|
width: 130,
|
|
minWidth: 120,
|
|
type: 'number',
|
|
aggregable: true,
|
|
headerAlign: 'right',
|
|
align: 'right',
|
|
valueFormatter: (value) => formatCurrency(value as number),
|
|
renderCell: (params: Readonly<GridRenderCellParams>) => (
|
|
<CellNumeric value={params.value} formatter={formatCurrency} fontWeight={500} />
|
|
),
|
|
},
|
|
{
|
|
field: 'totalWeight',
|
|
headerName: 'Peso (kg)',
|
|
width: 100,
|
|
minWidth: 90,
|
|
type: 'number',
|
|
aggregable: true,
|
|
headerAlign: 'right',
|
|
align: 'right',
|
|
valueFormatter: (value) => formatNumber(value as number),
|
|
renderCell: (params: Readonly<GridRenderCellParams>) => (
|
|
<CellNumeric value={params.value} formatter={formatNumber} />
|
|
),
|
|
},
|
|
|
|
|
|
{
|
|
field: 'invoiceNumber',
|
|
headerName: 'Nota Fiscal',
|
|
width: 120,
|
|
minWidth: 110,
|
|
headerAlign: 'right',
|
|
align: 'right',
|
|
renderCell: (params: Readonly<GridRenderCellParams>) => {
|
|
const value = params.value && params.value !== '-' ? params.value : '-';
|
|
return <CellNumeric value={value} />;
|
|
},
|
|
},
|
|
{
|
|
field: 'invoiceDate',
|
|
headerName: 'Data Faturamento',
|
|
width: 150,
|
|
minWidth: 140,
|
|
renderCell: (params: Readonly<GridRenderCellParams>) => (
|
|
<CellDate value={params.value} time={params.row.invoiceTime} />
|
|
),
|
|
},
|
|
{
|
|
field: 'fatUserName',
|
|
headerName: 'Usuário Faturou',
|
|
width: 160,
|
|
minWidth: 140,
|
|
renderCell: (params: Readonly<GridRenderCellParams>) => (
|
|
<CellText value={params.value} />
|
|
),
|
|
},
|
|
|
|
|
|
{
|
|
field: 'billingId',
|
|
headerName: 'Cobrança',
|
|
width: 120,
|
|
minWidth: 110,
|
|
renderCell: (params: Readonly<GridRenderCellParams>) => (
|
|
<CellText value={params.value} />
|
|
),
|
|
},
|
|
{
|
|
field: 'paymentName',
|
|
headerName: 'Pagamento',
|
|
width: 140,
|
|
minWidth: 130,
|
|
renderCell: (params: Readonly<GridRenderCellParams>) => (
|
|
<CellText value={params.value} />
|
|
),
|
|
},
|
|
|
|
|
|
{
|
|
field: 'sellerName',
|
|
headerName: 'Vendedor',
|
|
width: 200,
|
|
minWidth: 180,
|
|
renderCell: (params: Readonly<GridRenderCellParams>) => (
|
|
<CellText value={params.value} />
|
|
),
|
|
},
|
|
{
|
|
field: 'sellerId',
|
|
headerName: 'RCA',
|
|
width: 100,
|
|
minWidth: 90,
|
|
headerAlign: 'right',
|
|
align: 'right',
|
|
renderCell: (params: Readonly<GridRenderCellParams>) => (
|
|
<CellNumeric value={params.value} secondary />
|
|
),
|
|
},
|
|
{
|
|
field: 'codusur2Name',
|
|
headerName: 'RCA 2',
|
|
width: 180,
|
|
minWidth: 160,
|
|
renderCell: (params: Readonly<GridRenderCellParams>) => (
|
|
<CellText value={params.value} />
|
|
),
|
|
},
|
|
|
|
|
|
{
|
|
field: 'deliveryType',
|
|
headerName: 'Tipo de Entrega',
|
|
width: 160,
|
|
minWidth: 140,
|
|
renderCell: (params: Readonly<GridRenderCellParams>) => (
|
|
<CellText value={params.value} />
|
|
),
|
|
},
|
|
{
|
|
field: 'deliveryDate',
|
|
headerName: 'Data Entrega',
|
|
width: 130,
|
|
minWidth: 120,
|
|
renderCell: (params: Readonly<GridRenderCellParams>) => (
|
|
<CellDate value={params.value} />
|
|
),
|
|
},
|
|
{
|
|
field: 'deliveryLocal',
|
|
headerName: 'Local Entrega',
|
|
width: 180,
|
|
minWidth: 160,
|
|
renderCell: (params: Readonly<GridRenderCellParams>) => (
|
|
<CellText value={params.value} />
|
|
),
|
|
},
|
|
{
|
|
field: 'deliveryPriority',
|
|
headerName: 'Prioridade',
|
|
width: 120,
|
|
minWidth: 110,
|
|
renderCell: (params: Readonly<GridRenderCellParams>) => {
|
|
const priority = params.value;
|
|
const chipProps = getPriorityChipProps(priority);
|
|
|
|
if (!chipProps) {
|
|
return <CellText value="-" secondary />;
|
|
}
|
|
|
|
return (
|
|
<Tooltip title={chipProps.label} arrow placement="top">
|
|
<Chip
|
|
label={chipProps.label}
|
|
color={chipProps.color}
|
|
size="small"
|
|
sx={CHIP_PRIORITY_STYLES}
|
|
/>
|
|
</Tooltip>
|
|
);
|
|
},
|
|
},
|
|
{
|
|
field: 'confirmDeliveryDate',
|
|
headerName: 'Data Confirmação Entrega',
|
|
width: 150,
|
|
minWidth: 140,
|
|
renderCell: (params: Readonly<GridRenderCellParams>) => (
|
|
<CellDate value={params.value} />
|
|
),
|
|
},
|
|
{
|
|
field: 'schedulerDelivery',
|
|
headerName: 'Agendamento',
|
|
width: 160,
|
|
minWidth: 140,
|
|
renderCell: (params: Readonly<GridRenderCellParams>) => (
|
|
<CellText value={params.value} />
|
|
),
|
|
},
|
|
|
|
|
|
{
|
|
field: 'partnerName',
|
|
headerName: 'Parceiro',
|
|
width: 180,
|
|
minWidth: 160,
|
|
renderCell: (params: Readonly<GridRenderCellParams>) => (
|
|
<CellText value={params.value} />
|
|
),
|
|
},
|
|
{
|
|
field: 'emitenteNome',
|
|
headerName: 'Emitente',
|
|
width: 180,
|
|
minWidth: 160,
|
|
renderCell: (params: Readonly<GridRenderCellParams>) => (
|
|
<CellText value={params.value} />
|
|
),
|
|
},
|
|
];
|
|
};
|