import { PureComponent } from 'react'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; import Stack from '@mui/material/Stack'; import Table from '@mui/material/Table'; import TableBody from '@mui/material/TableBody'; import TableCell from '@mui/material/TableCell'; import TableContainer from '@mui/material/TableContainer'; import TableHead from '@mui/material/TableHead'; import TableRow from '@mui/material/TableRow'; import Typography from '@mui/material/Typography'; import AddIcon from '@mui/icons-material/Add'; import SearchIcon from '@mui/icons-material/Search'; import DeleteSweepOutlinedIcon from '@mui/icons-material/DeleteSweepOutlined'; import { PanelTile } from 'dashgui/panels'; import { LINE_COLUMNS, hasArticleLines, parseNum, getFirstVal } from './manifestConfig'; import { formatPrice } from '../../utils/price'; import ManifestFormLine from './ManifestFormLine'; class ManifestLines extends PureComponent { render() { const { kind = 'delivery', lines, saving, partyId, linesColor, dirtyLineFields = {}, shipments, onLineChange, onAddLine, onRemoveLine, onMoveLine, onRemoveAllLines, columns = LINE_COLUMNS, supplierArticlesMap = {}, supplierArticlesByLineKey = {}, supplierArticlesLoading = false, loadingLineKeys = {}, onSkuBlur, onCreateArticle, onSearchArticle, onRemoveSupplierArticle, busySupplierArticleLineKeys = {}, wide = 4, ledgerLinesById = {}, onBookLine, } = this.props; const hasArticles = hasArticleLines(lines); let totalNet = 0; let totalGross = 0; if (Array.isArray(lines)) { for (const line of lines) { const amount = parseNum(getFirstVal(line.amount, line.count)) ?? 0; const net = parseNum(getFirstVal(line.net, line.netprice, line.netPrice)) ?? 0; const tax = parseNum(getFirstVal(line.tax, line.taxrate, line.taxRate)) ?? 0; const rebate = parseNum(getFirstVal(line.rebate)) ?? 0; const lineNet = amount * net * (1 - rebate / 100); const lineGross = lineNet * (1 + tax / 100); totalNet += lineNet; totalGross += lineGross; } } return ( = 4 ? { gridColumn: { xs: '1 / -1', sm: '1 / -1', md: 'span 4' } } : {}), ...(!hasArticles ? { border: '1.5px solid', borderColor: 'error.main', } : {}), }} > {columns.map((col) => ( {col.label} ))} {(() => { const shippedSkus = new Set(); if (kind === 'order' && Array.isArray(shipments)) { for (const sh of shipments) { for (const sl of sh.lines || []) { if (sl.sku) shippedSkus.add(String(sl.sku).trim().toLowerCase()); } } } if (!lines || lines.length === 0) { return null; } return lines.map((line, index) => { const lineKey = line.key ?? index; const rawSku = line.sku != null ? String(line.sku).trim() : ''; const isOnShipment = kind === 'order' && Boolean(rawSku && shippedSkus.has(rawSku.toLowerCase())); const isDelivery = kind === 'delivery'; const matched = isDelivery ? supplierArticlesByLineKey[lineKey] || (rawSku ? supplierArticlesMap[rawSku.toLowerCase()] || supplierArticlesMap[rawSku] : null) : null; const isLineLoading = isDelivery ? loadingLineKeys[lineKey] || (supplierArticlesLoading && !matched) : false; const ledgerLine = line.id != null ? ledgerLinesById[line.id] : null; const lineDirtyFields = dirtyLineFields[lineKey] || (line.key != null ? dirtyLineFields[line.key] : null) || (line.id != null ? dirtyLineFields[`id-${line.id}`] : null) || dirtyLineFields[`idx-${index}`] || null; return ( ); }); })()}
{onSearchArticle && (() => { const searchArticleDisabled = saving || (kind === 'delivery' && !partyId); const searchArticleTitle = kind === 'delivery' && !partyId ? 'Bitte zuerst einen Lieferanten auswählen' : undefined; return ( ); })()} {(() => { const hasShippedLines = kind === 'order' && Array.isArray(shipments) && shipments.some((sh) => (sh.lines?.length || 0) > 0); const hasLedgeredLines = kind === 'delivery' && Array.isArray(lines) && lines.some((line) => { const ledgerLine = line?.id != null ? ledgerLinesById?.[line.id] : null; return Boolean( ledgerLine?.isBooked || (ledgerLine && ledgerLine.targetAmount > 0 && ledgerLine.remainingAmount <= 0) || (ledgerLine && ledgerLine.bookedAmount > 0) || line?.isBooked || line?.is_booked ); }); const disabled = saving || !lines || lines.length === 0 || hasShippedLines || hasLedgeredLines; const title = hasLedgeredLines ? 'Lieferung enthält bereits im Ledger verbuchte Positionen' : hasShippedLines ? 'Auftrag enthält bereits ausgelieferte Positionen' : 'Alle Zeilen entfernen'; return ( ); })()} {(totalNet > 0 || totalGross > 0) && ( Netto:{' '} {formatPrice(totalNet)} Brutto:{' '} {formatPrice(totalGross)} )}
); } } export default ManifestLines;