feat(delivery): add supplier article lookup, article creation, and unified parsing

- Unified PDF/TXT parsing to single POST /api/delivery/parse endpoint
- Added supplier article lookup with SKU/EAN matching in delivery lines
- Added "Artikel anlegen" button to create articles from missing SKUs
- Fixed delivery line taxrate field (was sending 'tax', now 'taxrate')
- Extended TXT file support for rescan functionality
- Updated ApiClient with getArticles method for supplier article lookup
- Added supplier article state management to deliveryEditorAutomat

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
seb
2026-09-18 04:39:07 +02:00
parent 27f6dfdebf
commit d5ade4923d
8 changed files with 670 additions and 91 deletions

View File

@@ -24,6 +24,12 @@ class ManifestLines extends PureComponent {
onRemoveLine,
onSave,
columns = LINE_COLUMNS,
supplierArticlesMap = {},
supplierArticlesByLineKey = {},
supplierArticlesLoading = false,
loadingLineKeys = {},
onSkuBlur,
onCreateArticle,
} = this.props;
return (
@@ -50,16 +56,31 @@ class ManifestLines extends PureComponent {
</TableRow>
</TableHead>
<TableBody>
{lines.map((line, index) => (
<ManifestFormLine
key={line.key ?? index}
line={line.key != null ? line : { ...line, key: index }}
columns={columns}
saving={saving}
onChange={onLineChange}
onRemove={onRemoveLine}
/>
))}
{lines.map((line, index) => {
const lineKey = line.key ?? index;
const rawSku = line.sku != null ? String(line.sku).trim() : '';
const matched =
supplierArticlesByLineKey[lineKey] ||
(rawSku ? supplierArticlesMap[rawSku.toLowerCase()] || supplierArticlesMap[rawSku] : null);
const isLineLoading =
loadingLineKeys[lineKey] ||
(supplierArticlesLoading && !matched);
return (
<ManifestFormLine
key={lineKey}
line={line.key != null ? line : { ...line, key: index }}
columns={columns}
saving={saving}
supplierArticle={matched}
loading={Boolean(isLineLoading)}
onChange={onLineChange}
onRemove={onRemoveLine}
onSkuBlur={onSkuBlur}
onCreateArticle={onCreateArticle}
/>
);
})}
</TableBody>
</Table>
</TableContainer>