diff --git a/src/components/manifest/BookDeliveryDialog.jsx b/src/components/manifest/BookDeliveryDialog.jsx
index 77d09c3..c2f9e5b 100644
--- a/src/components/manifest/BookDeliveryDialog.jsx
+++ b/src/components/manifest/BookDeliveryDialog.jsx
@@ -47,6 +47,7 @@ export default class BookDeliveryDialog extends PureComponent {
let initialAmounts = {};
if (Array.isArray(props.summary?.lines)) {
for (const line of props.summary.lines) {
+ if (!line.trackStock) continue;
if (props.prefillLineId != null) {
initialAmounts[line.id] =
line.id === props.prefillLineId
@@ -174,6 +175,7 @@ export default class BookDeliveryDialog extends PureComponent {
const amounts = {};
if (Array.isArray(summary?.lines)) {
for (const line of summary.lines) {
+ if (!line.trackStock) continue;
if (prefillLineId != null) {
amounts[line.id] =
line.id === prefillLineId
@@ -208,6 +210,7 @@ export default class BookDeliveryDialog extends PureComponent {
if (!summary?.lines) return;
const amounts = {};
for (const line of summary.lines) {
+ if (!line.trackStock) continue;
amounts[line.id] = line.remainingAmount > 0 ? line.remainingAmount : 0;
}
this.setState({ amountsToBook: amounts });
@@ -218,6 +221,7 @@ export default class BookDeliveryDialog extends PureComponent {
if (!summary?.lines) return;
const amounts = {};
for (const line of summary.lines) {
+ if (!line.trackStock) continue;
amounts[line.id] = 0;
}
this.setState({ amountsToBook: amounts });
@@ -229,6 +233,7 @@ export default class BookDeliveryDialog extends PureComponent {
if (!summary?.lines) return;
const linesToBook = summary.lines
+ .filter((line) => line.trackStock)
.map((line) => ({
manifestarticleId: line.id,
sku: line.sku,
@@ -382,12 +387,12 @@ export default class BookDeliveryDialog extends PureComponent {
renderLinesTable() {
const { summary, amountsToBook, isBooking } = this.state;
- const lines = summary?.lines || [];
+ const lines = (summary?.lines || []).filter((l) => l.trackStock);
if (lines.length === 0) {
return (
- Diese Lieferung enthält keine Artikelpositionen zum Einbuchen.
+ Diese Lieferung enthält keine lagergeführten Artikel zum Einbuchen.
);
}
@@ -490,7 +495,8 @@ export default class BookDeliveryDialog extends PureComponent {
warehouseError,
} = this.state;
- const lines = summary?.lines || [];
+ const lines = (summary?.lines || []).filter((l) => l.trackStock);
+ const hasTrackStock = lines.length > 0;
const prefillLine =
this.props.prefillLineId != null
? lines.find((l) => l.id === this.props.prefillLineId)
@@ -502,7 +508,7 @@ export default class BookDeliveryDialog extends PureComponent {
const countLinesToBook = lines.filter(
(l) => Number(amountsToBook[l.id]) > 0
).length;
- const isFullyBooked = summary?.status === 'booked';
+ const isFullyBooked = hasTrackStock && summary?.status === 'booked';
const selectedWarehouse = warehouses.find((w) => w.id === selectedWarehouseId);
const isWarehouseMissing = !selectedWarehouseId;
@@ -554,7 +560,7 @@ export default class BookDeliveryDialog extends PureComponent {
)}
{this.renderLinesTable()}
- {!isFullyBooked && lines.length > 0 && (
+ {!isFullyBooked && hasTrackStock && (
+ )}
{isFullyBooked ? (
}>
Alle Artikel dieser Lieferung sind bereits vollständig im Lager verbucht.
- ) : totalToBook > 0 ? (
+ ) : hasTrackStock && totalToBook > 0 ? (
{selectedWarehouseId ? (
<>
@@ -659,11 +667,11 @@ export default class BookDeliveryDialog extends PureComponent {
>
)}
- ) : (
+ ) : hasTrackStock ? (
Wählen Sie mindestens eine Menge größer als 0 aus, um den Lagerzugang zu buchen.
- )}
+ ) : null}
>
)}
diff --git a/src/components/manifest/ManifestFormLine.jsx b/src/components/manifest/ManifestFormLine.jsx
index ba23a20..bd99ab8 100644
--- a/src/components/manifest/ManifestFormLine.jsx
+++ b/src/components/manifest/ManifestFormLine.jsx
@@ -184,7 +184,7 @@ class ManifestFormLine extends PureComponent {
renderLedgerChip() {
const { ledgerLine, onBookLine } = this.props;
- if (!ledgerLine) return null;
+ if (!ledgerLine || !ledgerLine.trackStock) return null;
const isBooked = ledgerLine.isBooked;
const isPartial = !isBooked && ledgerLine.bookedAmount > 0;
const isClickable = Boolean(onBookLine);
diff --git a/src/components/manifest/ManifestHeader.jsx b/src/components/manifest/ManifestHeader.jsx
index 04c737d..43fd7eb 100644
--- a/src/components/manifest/ManifestHeader.jsx
+++ b/src/components/manifest/ManifestHeader.jsx
@@ -511,7 +511,7 @@ class ManifestHeader extends PureComponent {
Wiederherstellen
)}
- {docId != null && kind === 'delivery' && onOpenBookDialog && (
+ {docId != null && kind === 'delivery' && onOpenBookDialog && ledgerSummary?.hasTrackStock && (
+ {ledgerSummary.hasTrackStock && (
+
+ ) : (
+
+ )
+ }
+ onClick={this.handleOpenBookDialog}
+ sx={{ fontWeight: 600, textTransform: 'none' }}
+ >
+ {status === 'booked'
+ ? 'Buchungsdetails anzeigen'
+ : status === 'partial'
+ ? 'Restliche Mengen einbuchen'
+ : 'Ins Lager buchen'}
+
+ )}
{allEntries.length > 0 && (
diff --git a/src/utils/deliveryLedger.js b/src/utils/deliveryLedger.js
index 68fabfa..7a66560 100644
--- a/src/utils/deliveryLedger.js
+++ b/src/utils/deliveryLedger.js
@@ -1,5 +1,34 @@
import { delivery as defaultDeliveryApi, ledger as defaultLedgerApi } from '../api';
-import artikelAutomat from '../automats/artikelAutomat';
+import artikelAutomat, { getArticle } from '../automats/artikelAutomat';
+import articleIndexAutomat from '../automats/articleIndexAutomat';
+
+/**
+ * Determines whether a delivery line represents an article that tracks stock.
+ *
+ * @param {object} line Delivery line
+ * @param {object|null} [article] Optional pre-resolved article
+ * @returns {boolean}
+ */
+export function isLineStockTracked(line, article = null) {
+ if (!line) return false;
+ if (line.track_stock !== undefined) {
+ return line.track_stock !== false && line.track_stock !== 0 && line.track_stock !== '0';
+ }
+ if (line.trackStock !== undefined) {
+ return Boolean(line.trackStock);
+ }
+ if (line.article?.track_stock !== undefined) {
+ return line.article.track_stock !== false && line.article.track_stock !== 0 && line.article.track_stock !== '0';
+ }
+ const sku = line.sku ? String(line.sku).trim() : null;
+ if (!sku) return false;
+
+ const art = article || getArticle(sku) || articleIndexAutomat.state.items?.find((item) => String(item.sku) === sku);
+ if (art?.track_stock !== undefined) {
+ return art.track_stock !== false && art.track_stock !== 0 && art.track_stock !== '0';
+ }
+ return false;
+}
/**
* @typedef {Object} DeliveryLineLedgerStatus
@@ -10,6 +39,8 @@ import artikelAutomat from '../automats/artikelAutomat';
* @property {number} bookedAmount - Quantity booked in ledger
* @property {number} remainingAmount - Quantity remaining to be booked
* @property {boolean} isBooked - Whether this position is fully booked
+ * @property {boolean} trackStock - Whether this article tracks inventory
+ * @property {boolean} isBookable - Whether this position can be booked into the warehouse
* @property {Array