u
This commit is contained in:
@@ -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}
|
||||
|
||||
@@ -481,27 +481,45 @@ class ManifestHeader extends PureComponent {
|
||||
>
|
||||
{saving ? 'Speichern…' : 'Speichern'}
|
||||
</Button>
|
||||
{isDirty && onRestore && (
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="warning"
|
||||
size="small"
|
||||
startIcon={<RestoreIcon />}
|
||||
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
|
||||
</Button>
|
||||
)}
|
||||
{(() => {
|
||||
const canRestore = Boolean(onRestore && isDirty && !saving && !orderCreating);
|
||||
return (
|
||||
<Button
|
||||
variant="outlined"
|
||||
color={canRestore ? 'warning' : 'inherit'}
|
||||
size="small"
|
||||
startIcon={<RestoreIcon />}
|
||||
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
|
||||
</Button>
|
||||
);
|
||||
})()}
|
||||
{docId != null && kind === 'delivery' && onOpenBookDialog && Boolean(ledgerSummary && (ledgerSummary.totalPositions > 0 || ledgerSummary.lines?.length > 0 || ledgerSummary.hasTrackStock)) && (
|
||||
<Button
|
||||
variant={ledgerSummary?.status === 'booked' ? 'outlined' : 'contained'}
|
||||
@@ -561,27 +579,56 @@ class ManifestHeader extends PureComponent {
|
||||
{orderCreating ? 'Wird erstellt…' : 'Bestellung erstellen'}
|
||||
</Button>
|
||||
)}
|
||||
{(kind === 'quote' || kind === 'order' || kind === 'delivery') && onPdfCreate && docId != null && Boolean(number) && (
|
||||
<Button
|
||||
type="button"
|
||||
variant="outlined"
|
||||
startIcon={pdfCreating ? <CircularProgress size={16} color="inherit" /> : <PictureAsPdfIcon />}
|
||||
disabled={saving || pdfCreating || orderCreating}
|
||||
onClick={onPdfCreate}
|
||||
title="PDF erstellen"
|
||||
sx={{
|
||||
whiteSpace: 'nowrap',
|
||||
height: 40,
|
||||
width: '100%',
|
||||
px: 1.5,
|
||||
boxSizing: 'border-box',
|
||||
fontWeight: 600,
|
||||
fontSize: '0.875rem',
|
||||
}}
|
||||
>
|
||||
{pdfCreating ? 'Wird erstellt…' : 'PDF erstellen'}
|
||||
</Button>
|
||||
)}
|
||||
{(kind === 'quote' || kind === 'order' || kind === 'delivery') && (() => {
|
||||
const canCreatePdf = Boolean(
|
||||
onPdfCreate &&
|
||||
docId != null &&
|
||||
Boolean(number) &&
|
||||
!saving &&
|
||||
!pdfCreating &&
|
||||
!orderCreating
|
||||
);
|
||||
return (
|
||||
<Button
|
||||
type="button"
|
||||
variant="outlined"
|
||||
color={canCreatePdf ? 'primary' : 'inherit'}
|
||||
startIcon={pdfCreating ? <CircularProgress size={16} color="inherit" /> : <PictureAsPdfIcon />}
|
||||
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'}
|
||||
</Button>
|
||||
);
|
||||
})()}
|
||||
{onPdfUpload ? (
|
||||
<FileDropzone
|
||||
accept="application/pdf,.pdf,text/plain,.txt,text/csv,.csv"
|
||||
|
||||
@@ -199,22 +199,42 @@ class ManifestLines extends PureComponent {
|
||||
);
|
||||
})()}
|
||||
{(() => {
|
||||
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 (
|
||||
<Button
|
||||
|
||||
@@ -160,6 +160,7 @@ class LieferungNeuPage extends PureComponent {
|
||||
this.handleRemoveLine = this.handleRemoveLine.bind(this);
|
||||
this.handleMoveLine = this.handleMoveLine.bind(this);
|
||||
this.handleRemoveAllLines = this.handleRemoveAllLines.bind(this);
|
||||
this.handleRestore = this.handleRestore.bind(this);
|
||||
this.handleSave = this.handleSave.bind(this);
|
||||
this.handlePdfUpload = this.handlePdfUpload.bind(this);
|
||||
this.handlePdfRescan = this.handlePdfRescan.bind(this);
|
||||
@@ -686,6 +687,24 @@ class LieferungNeuPage extends PureComponent {
|
||||
|
||||
handleRemoveAllLines() {
|
||||
this.automat.actions.clearLineitems();
|
||||
this.setState({ lines: [] });
|
||||
}
|
||||
|
||||
handleRestore() {
|
||||
if (!this._initialDoc) return;
|
||||
const base = this._initialDoc;
|
||||
this.automat.actions.setDate(base.date);
|
||||
if (base.partyId != null) {
|
||||
this.automat.actions.setDeliveryEntity(base.partyId);
|
||||
}
|
||||
this.automat.actions.setExternalNumber(base.externalNumber || '');
|
||||
const restoredLines = (base.lines || []).map((l) => ({ ...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}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user