u
This commit is contained in:
@@ -254,20 +254,11 @@ export default class ArticleSupplierTab extends PureComponent {
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
justifyContent: 'flex-end',
|
||||
alignItems: 'center',
|
||||
mb: 2,
|
||||
}}
|
||||
>
|
||||
<Box>
|
||||
<Typography variant="subtitle1" sx={{ fontWeight: 600 }}>
|
||||
Zugeordnete Lieferanten ({assignedSuppliers.length})
|
||||
</Typography>
|
||||
<Typography variant="caption" color="text.secondary">
|
||||
Bezugsquellen, Lieferanten-Artikelnr. und Konditionen für diesen Artikel
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<Button
|
||||
size="small"
|
||||
variant="contained"
|
||||
@@ -279,200 +270,166 @@ export default class ArticleSupplierTab extends PureComponent {
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
{/* Content Table or Empty State */}
|
||||
{assignedSuppliers.length === 0 ? (
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
py: 6,
|
||||
px: 2,
|
||||
borderRadius: 2,
|
||||
border: `1px dashed ${SORT_GHOST_BG}`,
|
||||
bgcolor: TINT_FAINT,
|
||||
textAlign: 'center',
|
||||
}}
|
||||
>
|
||||
<LocalShippingOutlinedIcon sx={{ fontSize: 48, mb: 1.5, color: 'text.secondary', opacity: 0.6 }} />
|
||||
<Typography variant="subtitle2" sx={{ fontWeight: 600, mb: 0.5 }}>
|
||||
Noch keine Lieferanten zugewiesen
|
||||
</Typography>
|
||||
<Typography variant="body2" color="text.secondary" sx={{ maxWidth: 380, mb: 2 }}>
|
||||
Weise diesem Artikel Lieferanten zu, um Einkaufspreise, VPE und Artikelnummern für Wareneingänge zu hinterlegen.
|
||||
</Typography>
|
||||
<Button
|
||||
variant="outlined"
|
||||
startIcon={<AddIcon />}
|
||||
onClick={this.handleOpenAdd}
|
||||
size="small"
|
||||
sx={{ textTransform: 'none' }}
|
||||
>
|
||||
Jetzt Lieferant zuweisen
|
||||
</Button>
|
||||
</Box>
|
||||
) : (
|
||||
<Table
|
||||
size="small"
|
||||
sx={{
|
||||
'& td': { verticalAlign: 'middle' },
|
||||
'& th': { fontWeight: 600, color: 'text.secondary', fontSize: '0.8rem' },
|
||||
}}
|
||||
>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell sx={{ width: 60, pl: 1 }}>Reihe</TableCell>
|
||||
<TableCell>Lieferant</TableCell>
|
||||
<TableCell>Lief.-Art.-Nr.</TableCell>
|
||||
<TableCell align="right">VPE (PU)</TableCell>
|
||||
<TableCell align="right">Lagerbestand</TableCell>
|
||||
<TableCell align="right">Einkaufspreis</TableCell>
|
||||
<TableCell align="right" sx={{ width: 100, pr: 1 }}>
|
||||
Aktionen
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{assignedSuppliers.map((row, index) => {
|
||||
const isBusy = busyId === row.id;
|
||||
const netPrice = row.price?.net;
|
||||
const taxRate = row.price?.taxRate;
|
||||
{/* Content Table */}
|
||||
<Table
|
||||
size="small"
|
||||
sx={{
|
||||
'& td': { verticalAlign: 'middle' },
|
||||
'& th': { fontWeight: 600, color: 'text.secondary', fontSize: '0.8rem' },
|
||||
}}
|
||||
>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell sx={{ width: 60, pl: 1 }}>Reihe</TableCell>
|
||||
<TableCell>Lieferant</TableCell>
|
||||
<TableCell>Lief.-Art.-Nr.</TableCell>
|
||||
<TableCell align="right">VPE (PU)</TableCell>
|
||||
<TableCell align="right">Lagerbestand</TableCell>
|
||||
<TableCell align="right">Einkaufspreis</TableCell>
|
||||
<TableCell align="right" sx={{ width: 100, pr: 1 }}>
|
||||
Aktionen
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{assignedSuppliers.map((row, index) => {
|
||||
const isBusy = busyId === row.id;
|
||||
const netPrice = row.price?.net;
|
||||
const taxRate = row.price?.taxRate;
|
||||
|
||||
return (
|
||||
<TableRow
|
||||
key={row.id}
|
||||
hover
|
||||
sx={{
|
||||
opacity: isBusy ? 0.5 : 1,
|
||||
transition: 'opacity 0.2s',
|
||||
}}
|
||||
>
|
||||
{/* Sort Order & Reorder Controls */}
|
||||
<TableCell sx={{ pl: 1 }}>
|
||||
<Stack direction="row" spacing={0.5} alignItems="center">
|
||||
<Typography variant="caption" sx={{ minWidth: 16, fontWeight: 700, color: 'text.secondary' }}>
|
||||
{index + 1}
|
||||
return (
|
||||
<TableRow
|
||||
key={row.id}
|
||||
hover
|
||||
sx={{
|
||||
opacity: isBusy ? 0.5 : 1,
|
||||
transition: 'opacity 0.2s',
|
||||
}}
|
||||
>
|
||||
{/* Sort Order & Reorder Controls */}
|
||||
<TableCell sx={{ pl: 1 }}>
|
||||
<Stack direction="row" spacing={0.5} alignItems="center">
|
||||
<Typography variant="caption" sx={{ minWidth: 16, fontWeight: 700, color: 'text.secondary' }}>
|
||||
{index + 1}
|
||||
</Typography>
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column' }}>
|
||||
<Tooltip title="Nach oben">
|
||||
<span>
|
||||
<IconButton
|
||||
size="small"
|
||||
disabled={index === 0 || isBusy}
|
||||
onClick={() => this.handleMove(index, -1)}
|
||||
sx={{ p: 0.2 }}
|
||||
>
|
||||
<ArrowUpwardIcon sx={{ fontSize: 13 }} />
|
||||
</IconButton>
|
||||
</span>
|
||||
</Tooltip>
|
||||
<Tooltip title="Nach unten">
|
||||
<span>
|
||||
<IconButton
|
||||
size="small"
|
||||
disabled={index === assignedSuppliers.length - 1 || isBusy}
|
||||
onClick={() => this.handleMove(index, 1)}
|
||||
sx={{ p: 0.2 }}
|
||||
>
|
||||
<ArrowDownwardIcon sx={{ fontSize: 13 }} />
|
||||
</IconButton>
|
||||
</span>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
</Stack>
|
||||
</TableCell>
|
||||
|
||||
{/* Supplier Name */}
|
||||
<TableCell sx={{ fontWeight: 600 }}>
|
||||
{row.supplierName ?? `Lieferant #${row.entityId}`}
|
||||
</TableCell>
|
||||
|
||||
{/* Supplier SKU */}
|
||||
<TableCell>
|
||||
{row.sku ? (
|
||||
<Typography variant="body2" sx={{ fontFamily: 'monospace', fontWeight: 500 }}>
|
||||
{row.sku}
|
||||
</Typography>
|
||||
) : (
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
—
|
||||
</Typography>
|
||||
)}
|
||||
</TableCell>
|
||||
|
||||
{/* PU / VPE */}
|
||||
<TableCell align="right">
|
||||
<Typography variant="body2">{row.pu ?? 1}</Typography>
|
||||
</TableCell>
|
||||
|
||||
{/* Stock */}
|
||||
<TableCell align="right">
|
||||
{row.stock != null ? (
|
||||
<Chip
|
||||
size="small"
|
||||
label={`${row.stock} Stk`}
|
||||
color={row.stock > 0 ? 'success' : 'default'}
|
||||
variant="outlined"
|
||||
sx={{ fontWeight: 500, height: 22, fontSize: '0.75rem' }}
|
||||
/>
|
||||
) : (
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
—
|
||||
</Typography>
|
||||
)}
|
||||
</TableCell>
|
||||
|
||||
{/* Purchase Price Net & Tax */}
|
||||
<TableCell align="right">
|
||||
{netPrice != null ? (
|
||||
<Box>
|
||||
<Typography variant="body2" sx={{ fontWeight: 600 }}>
|
||||
{formatPrice(netPrice)}
|
||||
</Typography>
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column' }}>
|
||||
<Tooltip title="Nach oben">
|
||||
<span>
|
||||
<IconButton
|
||||
size="small"
|
||||
disabled={index === 0 || isBusy}
|
||||
onClick={() => this.handleMove(index, -1)}
|
||||
sx={{ p: 0.2 }}
|
||||
>
|
||||
<ArrowUpwardIcon sx={{ fontSize: 13 }} />
|
||||
</IconButton>
|
||||
</span>
|
||||
</Tooltip>
|
||||
<Tooltip title="Nach unten">
|
||||
<span>
|
||||
<IconButton
|
||||
size="small"
|
||||
disabled={index === assignedSuppliers.length - 1 || isBusy}
|
||||
onClick={() => this.handleMove(index, 1)}
|
||||
sx={{ p: 0.2 }}
|
||||
>
|
||||
<ArrowDownwardIcon sx={{ fontSize: 13 }} />
|
||||
</IconButton>
|
||||
</span>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
</Stack>
|
||||
</TableCell>
|
||||
|
||||
{/* Supplier Name */}
|
||||
<TableCell sx={{ fontWeight: 600 }}>
|
||||
{row.supplierName ?? `Lieferant #${row.entityId}`}
|
||||
</TableCell>
|
||||
|
||||
{/* Supplier SKU */}
|
||||
<TableCell>
|
||||
{row.sku ? (
|
||||
<Typography variant="body2" sx={{ fontFamily: 'monospace', fontWeight: 500 }}>
|
||||
{row.sku}
|
||||
</Typography>
|
||||
) : (
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
—
|
||||
</Typography>
|
||||
)}
|
||||
</TableCell>
|
||||
|
||||
{/* PU / VPE */}
|
||||
<TableCell align="right">
|
||||
<Typography variant="body2">{row.pu ?? 1}</Typography>
|
||||
</TableCell>
|
||||
|
||||
{/* Stock */}
|
||||
<TableCell align="right">
|
||||
{row.stock != null ? (
|
||||
<Chip
|
||||
size="small"
|
||||
label={`${row.stock} Stk`}
|
||||
color={row.stock > 0 ? 'success' : 'default'}
|
||||
variant="outlined"
|
||||
sx={{ fontWeight: 500, height: 22, fontSize: '0.75rem' }}
|
||||
/>
|
||||
) : (
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
—
|
||||
</Typography>
|
||||
)}
|
||||
</TableCell>
|
||||
|
||||
{/* Purchase Price Net & Tax */}
|
||||
<TableCell align="right">
|
||||
{netPrice != null ? (
|
||||
<Box>
|
||||
<Typography variant="body2" sx={{ fontWeight: 600 }}>
|
||||
{formatPrice(netPrice)}
|
||||
{taxRate != null ? (
|
||||
<Typography variant="caption" color="text.secondary">
|
||||
zzgl. {taxRate} % MwSt.
|
||||
</Typography>
|
||||
{taxRate != null ? (
|
||||
<Typography variant="caption" color="text.secondary">
|
||||
zzgl. {taxRate} % MwSt.
|
||||
</Typography>
|
||||
) : null}
|
||||
</Box>
|
||||
) : (
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
—
|
||||
</Typography>
|
||||
)}
|
||||
</TableCell>
|
||||
) : null}
|
||||
</Box>
|
||||
) : (
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
—
|
||||
</Typography>
|
||||
)}
|
||||
</TableCell>
|
||||
|
||||
{/* Actions */}
|
||||
<TableCell align="right" sx={{ pr: 1 }}>
|
||||
<Stack direction="row" spacing={0.5} justifyContent="flex-end">
|
||||
<Tooltip title="Bearbeiten">
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={() => this.handleOpenEdit(row)}
|
||||
disabled={isBusy}
|
||||
>
|
||||
<EditOutlinedIcon fontSize="small" />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip title="Entfernen">
|
||||
<IconButton
|
||||
size="small"
|
||||
color="error"
|
||||
onClick={() => this.handleDelete(row)}
|
||||
disabled={isBusy}
|
||||
>
|
||||
<DeleteOutlineOutlinedIcon fontSize="small" />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</Stack>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
)}
|
||||
{/* Actions */}
|
||||
<TableCell align="right" sx={{ pr: 1 }}>
|
||||
<Stack direction="row" spacing={0.5} justifyContent="flex-end">
|
||||
<Tooltip title="Bearbeiten">
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={() => this.handleOpenEdit(row)}
|
||||
disabled={isBusy}
|
||||
>
|
||||
<EditOutlinedIcon fontSize="small" />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip title="Entfernen">
|
||||
<IconButton
|
||||
size="small"
|
||||
color="error"
|
||||
onClick={() => this.handleDelete(row)}
|
||||
disabled={isBusy}
|
||||
>
|
||||
<DeleteOutlineOutlinedIcon fontSize="small" />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</Stack>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
|
||||
{/* Add / Edit Dialog */}
|
||||
<ArticleSupplierDialog
|
||||
|
||||
Reference in New Issue
Block a user