diff --git a/src/components/manifest/ManifestForm.jsx b/src/components/manifest/ManifestForm.jsx
index d530ef5..8cce2fe 100644
--- a/src/components/manifest/ManifestForm.jsx
+++ b/src/components/manifest/ManifestForm.jsx
@@ -868,6 +868,7 @@ class ManifestForm extends PureComponent {
handleRemoveAllLines() {
this.setState((prev) => {
+ let nextLines = [];
if (this.props.kind === 'order') {
const shippedSkus = new Set();
for (const sh of prev.shipments || []) {
@@ -876,7 +877,7 @@ class ManifestForm extends PureComponent {
}
}
if (shippedSkus.size > 0) {
- const remaining = prev.lines.filter((l) => {
+ const remaining = (prev.lines || []).filter((l) => {
const raw = l.sku != null ? String(l.sku).trim().toLowerCase() : '';
return shippedSkus.has(raw);
});
@@ -885,10 +886,10 @@ class ManifestForm extends PureComponent {
return null;
}
enqueueSnackbar('Nicht ausgelieferte Positionen wurden entfernt.', { variant: 'info' });
- return { lines: remaining, isDirty: true };
+ nextLines = remaining;
}
}
- return { lines: [], isDirty: true };
+ return { lines: nextLines, isDirty: true };
});
}
@@ -1181,7 +1182,7 @@ class ManifestForm extends PureComponent {
{
kind: cfg.kind,
partyField: cfg.partyField,
- requireAtLeastOne: true,
+ requireAtLeastOne: !isEdit,
externalNumber: cfg.externalNumber,
isUpdate: isEdit,
mode,
@@ -1334,7 +1335,7 @@ class ManifestForm extends PureComponent {
isDirty={this.state.isDirty}
dirtyFields={this.state.dirtyFields}
dirtySummary={this.state.dirtySummary}
- onRestore={this.props.mode === 'edit' && this.state.isDirty ? this.handleRestore : undefined}
+ onRestore={this.props.mode === 'edit' ? this.handleRestore : undefined}
onPdfUpload={kind === 'delivery' ? this.handlePdfUpload : undefined}
onPdfDelete={this.handleAttachmentDelete}
onPdfCreate={kind === 'quote' || kind === 'order' ? this.handleCreatePdf : undefined}
diff --git a/src/components/manifest/ManifestHeader.jsx b/src/components/manifest/ManifestHeader.jsx
index b486a7d..6347547 100644
--- a/src/components/manifest/ManifestHeader.jsx
+++ b/src/components/manifest/ManifestHeader.jsx
@@ -481,27 +481,45 @@ class ManifestHeader extends PureComponent {
>
{saving ? 'Speichern…' : 'Speichern'}
- {isDirty && onRestore && (
- }
- disabled={saving || orderCreating}
- onClick={onRestore}
- sx={{
- height: 34,
- fontWeight: 700,
- fontSize: '0.8rem',
- whiteSpace: 'nowrap',
- textTransform: 'none',
- borderWidth: 1.5,
- '&:hover': { borderWidth: 1.5 },
- }}
- >
- Wiederherstellen
-
- )}
+ {(() => {
+ const canRestore = Boolean(onRestore && isDirty && !saving && !orderCreating);
+ return (
+ }
+ disabled={!canRestore}
+ onClick={canRestore ? onRestore : undefined}
+ title={
+ canRestore
+ ? 'Änderungen verwerfen und ursprünglichen Stand wiederherstellen'
+ : 'Keine Änderungen zum Wiederherstellen'
+ }
+ sx={{
+ height: 34,
+ width: '100%',
+ fontWeight: 700,
+ fontSize: '0.8rem',
+ whiteSpace: 'nowrap',
+ textTransform: 'none',
+ borderWidth: 1.5,
+ '&:hover': { borderWidth: 1.5 },
+ ...(!canRestore && {
+ borderColor: 'action.disabled',
+ color: 'text.disabled',
+ '&.Mui-disabled': {
+ borderColor: 'action.disabled',
+ color: 'text.disabled',
+ borderWidth: 1.5,
+ },
+ }),
+ }}
+ >
+ Wiederherstellen
+
+ );
+ })()}
{docId != null && kind === 'delivery' && onOpenBookDialog && Boolean(ledgerSummary && (ledgerSummary.totalPositions > 0 || ledgerSummary.lines?.length > 0 || ledgerSummary.hasTrackStock)) && (
- )}
+ {(kind === 'quote' || kind === 'order' || kind === 'delivery') && (() => {
+ const canCreatePdf = Boolean(
+ onPdfCreate &&
+ docId != null &&
+ Boolean(number) &&
+ !saving &&
+ !pdfCreating &&
+ !orderCreating
+ );
+ return (
+ : }
+ disabled={!canCreatePdf}
+ onClick={canCreatePdf ? onPdfCreate : undefined}
+ title={
+ pdfCreating
+ ? 'PDF wird erstellt…'
+ : canCreatePdf
+ ? 'PDF erstellen'
+ : docId == null
+ ? 'PDF kann erst nach dem Speichern erstellt werden'
+ : !number
+ ? 'Dokumentnummer erforderlich für PDF'
+ : 'PDF erstellen'
+ }
+ sx={{
+ whiteSpace: 'nowrap',
+ height: 40,
+ width: '100%',
+ px: 1.5,
+ boxSizing: 'border-box',
+ fontWeight: 600,
+ fontSize: '0.875rem',
+ ...(!canCreatePdf && {
+ borderColor: 'action.disabled',
+ color: 'text.disabled',
+ '&.Mui-disabled': {
+ borderColor: 'action.disabled',
+ color: 'text.disabled',
+ },
+ }),
+ }}
+ >
+ {pdfCreating ? 'Wird erstellt…' : 'PDF erstellen'}
+
+ );
+ })()}
{onPdfUpload ? (
{
- 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'
+ 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());
+ }
+ }
+ }
+ const allLinesShipped =
+ kind === 'order' &&
+ shippedSkus.size > 0 &&
+ Array.isArray(lines) &&
+ lines.length > 0 &&
+ lines.every((l) => {
+ const raw = l?.sku != null ? String(l.sku).trim().toLowerCase() : '';
+ return raw && shippedSkus.has(raw);
+ });
+ const allLinesLedgered =
+ kind === 'delivery' &&
+ Array.isArray(lines) &&
+ lines.length > 0 &&
+ lines.every((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 || allLinesShipped || allLinesLedgered;
+ const title = allLinesLedgered
+ ? 'Alle Positionen der Lieferung sind bereits im Ledger verbucht'
+ : allLinesShipped
+ ? 'Alle Positionen des Auftrags sind bereits ausgeliefert'
: 'Alle Zeilen entfernen';
return (
({ ...l }));
+ this.automat.actions.setLineitems(restoredLines);
+ this.automat.actions.setAttachments([...(base.attachments || [])]);
+ this.setState({
+ lines: restoredLines,
+ });
+ enqueueSnackbar('Änderungen verworfen und ursprünglicher Stand wiederhergestellt.', { variant: 'info' });
}
async handlePdfUpload(file) {
@@ -1331,6 +1350,7 @@ class LieferungNeuPage extends PureComponent {
onNumberChange={this.handleNumberChange}
onExternalNumberChange={this.handleExternalNumberChange}
docId={this.props.docId}
+ onRestore={isEdit ? this.handleRestore : undefined}
ledgerSummary={this.state.ledgerSummary}
onOpenBookDialog={this.handleOpenBookDialog}
/>