u
This commit is contained in:
@@ -47,6 +47,7 @@ export default class BookDeliveryDialog extends PureComponent {
|
|||||||
let initialAmounts = {};
|
let initialAmounts = {};
|
||||||
if (Array.isArray(props.summary?.lines)) {
|
if (Array.isArray(props.summary?.lines)) {
|
||||||
for (const line of props.summary.lines) {
|
for (const line of props.summary.lines) {
|
||||||
|
if (!line.trackStock) continue;
|
||||||
if (props.prefillLineId != null) {
|
if (props.prefillLineId != null) {
|
||||||
initialAmounts[line.id] =
|
initialAmounts[line.id] =
|
||||||
line.id === props.prefillLineId
|
line.id === props.prefillLineId
|
||||||
@@ -174,6 +175,7 @@ export default class BookDeliveryDialog extends PureComponent {
|
|||||||
const amounts = {};
|
const amounts = {};
|
||||||
if (Array.isArray(summary?.lines)) {
|
if (Array.isArray(summary?.lines)) {
|
||||||
for (const line of summary.lines) {
|
for (const line of summary.lines) {
|
||||||
|
if (!line.trackStock) continue;
|
||||||
if (prefillLineId != null) {
|
if (prefillLineId != null) {
|
||||||
amounts[line.id] =
|
amounts[line.id] =
|
||||||
line.id === prefillLineId
|
line.id === prefillLineId
|
||||||
@@ -208,6 +210,7 @@ export default class BookDeliveryDialog extends PureComponent {
|
|||||||
if (!summary?.lines) return;
|
if (!summary?.lines) return;
|
||||||
const amounts = {};
|
const amounts = {};
|
||||||
for (const line of summary.lines) {
|
for (const line of summary.lines) {
|
||||||
|
if (!line.trackStock) continue;
|
||||||
amounts[line.id] = line.remainingAmount > 0 ? line.remainingAmount : 0;
|
amounts[line.id] = line.remainingAmount > 0 ? line.remainingAmount : 0;
|
||||||
}
|
}
|
||||||
this.setState({ amountsToBook: amounts });
|
this.setState({ amountsToBook: amounts });
|
||||||
@@ -218,6 +221,7 @@ export default class BookDeliveryDialog extends PureComponent {
|
|||||||
if (!summary?.lines) return;
|
if (!summary?.lines) return;
|
||||||
const amounts = {};
|
const amounts = {};
|
||||||
for (const line of summary.lines) {
|
for (const line of summary.lines) {
|
||||||
|
if (!line.trackStock) continue;
|
||||||
amounts[line.id] = 0;
|
amounts[line.id] = 0;
|
||||||
}
|
}
|
||||||
this.setState({ amountsToBook: amounts });
|
this.setState({ amountsToBook: amounts });
|
||||||
@@ -229,6 +233,7 @@ export default class BookDeliveryDialog extends PureComponent {
|
|||||||
if (!summary?.lines) return;
|
if (!summary?.lines) return;
|
||||||
|
|
||||||
const linesToBook = summary.lines
|
const linesToBook = summary.lines
|
||||||
|
.filter((line) => line.trackStock)
|
||||||
.map((line) => ({
|
.map((line) => ({
|
||||||
manifestarticleId: line.id,
|
manifestarticleId: line.id,
|
||||||
sku: line.sku,
|
sku: line.sku,
|
||||||
@@ -382,12 +387,12 @@ export default class BookDeliveryDialog extends PureComponent {
|
|||||||
|
|
||||||
renderLinesTable() {
|
renderLinesTable() {
|
||||||
const { summary, amountsToBook, isBooking } = this.state;
|
const { summary, amountsToBook, isBooking } = this.state;
|
||||||
const lines = summary?.lines || [];
|
const lines = (summary?.lines || []).filter((l) => l.trackStock);
|
||||||
|
|
||||||
if (lines.length === 0) {
|
if (lines.length === 0) {
|
||||||
return (
|
return (
|
||||||
<Alert severity="info" sx={{ my: 2 }}>
|
<Alert severity="info" sx={{ my: 2 }}>
|
||||||
Diese Lieferung enthält keine Artikelpositionen zum Einbuchen.
|
Diese Lieferung enthält keine lagergeführten Artikel zum Einbuchen.
|
||||||
</Alert>
|
</Alert>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -490,7 +495,8 @@ export default class BookDeliveryDialog extends PureComponent {
|
|||||||
warehouseError,
|
warehouseError,
|
||||||
} = this.state;
|
} = this.state;
|
||||||
|
|
||||||
const lines = summary?.lines || [];
|
const lines = (summary?.lines || []).filter((l) => l.trackStock);
|
||||||
|
const hasTrackStock = lines.length > 0;
|
||||||
const prefillLine =
|
const prefillLine =
|
||||||
this.props.prefillLineId != null
|
this.props.prefillLineId != null
|
||||||
? lines.find((l) => l.id === this.props.prefillLineId)
|
? lines.find((l) => l.id === this.props.prefillLineId)
|
||||||
@@ -502,7 +508,7 @@ export default class BookDeliveryDialog extends PureComponent {
|
|||||||
const countLinesToBook = lines.filter(
|
const countLinesToBook = lines.filter(
|
||||||
(l) => Number(amountsToBook[l.id]) > 0
|
(l) => Number(amountsToBook[l.id]) > 0
|
||||||
).length;
|
).length;
|
||||||
const isFullyBooked = summary?.status === 'booked';
|
const isFullyBooked = hasTrackStock && summary?.status === 'booked';
|
||||||
const selectedWarehouse = warehouses.find((w) => w.id === selectedWarehouseId);
|
const selectedWarehouse = warehouses.find((w) => w.id === selectedWarehouseId);
|
||||||
const isWarehouseMissing = !selectedWarehouseId;
|
const isWarehouseMissing = !selectedWarehouseId;
|
||||||
|
|
||||||
@@ -554,7 +560,7 @@ export default class BookDeliveryDialog extends PureComponent {
|
|||||||
)}
|
)}
|
||||||
{this.renderLinesTable()}
|
{this.renderLinesTable()}
|
||||||
|
|
||||||
{!isFullyBooked && lines.length > 0 && (
|
{!isFullyBooked && hasTrackStock && (
|
||||||
<Box sx={{ display: 'flex', gap: 1, mb: 2 }}>
|
<Box sx={{ display: 'flex', gap: 1, mb: 2 }}>
|
||||||
<Button
|
<Button
|
||||||
size="small"
|
size="small"
|
||||||
@@ -576,75 +582,77 @@ export default class BookDeliveryDialog extends PureComponent {
|
|||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{warehouses.length === 0 && !isFullyBooked && (
|
{hasTrackStock && warehouses.length === 0 && !isFullyBooked && (
|
||||||
<Alert severity="error" sx={{ mb: 2 }}>
|
<Alert severity="error" sx={{ mb: 2 }}>
|
||||||
Es ist noch kein Lager eingerichtet. Bitte legen Sie unter „Artikel → Lager“ zuerst ein Lager an.
|
Es ist noch kein Lager eingerichtet. Bitte legen Sie unter „Artikel → Lager“ zuerst ein Lager an.
|
||||||
</Alert>
|
</Alert>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Box
|
{hasTrackStock && (
|
||||||
sx={{
|
<Box
|
||||||
display: 'flex',
|
sx={{
|
||||||
gap: 2,
|
display: 'flex',
|
||||||
mb: 2,
|
gap: 2,
|
||||||
flexDirection: { xs: 'column', sm: 'row' },
|
mb: 2,
|
||||||
}}
|
flexDirection: { xs: 'column', sm: 'row' },
|
||||||
>
|
}}
|
||||||
<FormControl
|
|
||||||
size="small"
|
|
||||||
required
|
|
||||||
error={Boolean(warehouseError)}
|
|
||||||
disabled={isBooking || isFullyBooked}
|
|
||||||
sx={{ minWidth: { sm: 240 }, flex: { sm: '0 0 auto' } }}
|
|
||||||
>
|
>
|
||||||
<InputLabel id="warehouse-select-label">Ziellager *</InputLabel>
|
<FormControl
|
||||||
<Select
|
size="small"
|
||||||
labelId="warehouse-select-label"
|
required
|
||||||
id="warehouse-select"
|
error={Boolean(warehouseError)}
|
||||||
value={selectedWarehouseId ?? ''}
|
disabled={isBooking || isFullyBooked}
|
||||||
label="Ziellager *"
|
sx={{ minWidth: { sm: 240 }, flex: { sm: '0 0 auto' } }}
|
||||||
onChange={this.handleWarehouseChange}
|
|
||||||
startAdornment={
|
|
||||||
<WarehouseIcon
|
|
||||||
sx={{ mr: 1, color: 'text.secondary', fontSize: 20 }}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
{warehouses.length === 0 ? (
|
<InputLabel id="warehouse-select-label">Ziellager *</InputLabel>
|
||||||
<MenuItem value="" disabled>
|
<Select
|
||||||
Keine Lager vorhanden
|
labelId="warehouse-select-label"
|
||||||
</MenuItem>
|
id="warehouse-select"
|
||||||
) : (
|
value={selectedWarehouseId ?? ''}
|
||||||
warehouses.map((wh) => (
|
label="Ziellager *"
|
||||||
<MenuItem key={wh.id} value={wh.id}>
|
onChange={this.handleWarehouseChange}
|
||||||
{wh.name}
|
startAdornment={
|
||||||
|
<WarehouseIcon
|
||||||
|
sx={{ mr: 1, color: 'text.secondary', fontSize: 20 }}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{warehouses.length === 0 ? (
|
||||||
|
<MenuItem value="" disabled>
|
||||||
|
Keine Lager vorhanden
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
))
|
) : (
|
||||||
|
warehouses.map((wh) => (
|
||||||
|
<MenuItem key={wh.id} value={wh.id}>
|
||||||
|
{wh.name}
|
||||||
|
</MenuItem>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</Select>
|
||||||
|
{warehouseError ? (
|
||||||
|
<FormHelperText>{warehouseError}</FormHelperText>
|
||||||
|
) : (
|
||||||
|
<FormHelperText>Pflichtfeld: Ziellager für die Buchung</FormHelperText>
|
||||||
)}
|
)}
|
||||||
</Select>
|
</FormControl>
|
||||||
{warehouseError ? (
|
|
||||||
<FormHelperText>{warehouseError}</FormHelperText>
|
|
||||||
) : (
|
|
||||||
<FormHelperText>Pflichtfeld: Ziellager für die Buchung</FormHelperText>
|
|
||||||
)}
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<TextField
|
<TextField
|
||||||
fullWidth
|
fullWidth
|
||||||
size="small"
|
size="small"
|
||||||
label="Buchungstext (Ledger-Referenz)"
|
label="Buchungstext (Ledger-Referenz)"
|
||||||
value={transactionText}
|
value={transactionText}
|
||||||
onChange={this.handleTransactionTextChange}
|
onChange={this.handleTransactionTextChange}
|
||||||
disabled={isBooking || isFullyBooked}
|
disabled={isBooking || isFullyBooked}
|
||||||
helperText="Wird als Transaktionstext in das Ledger übernommen"
|
helperText="Wird als Transaktionstext in das Ledger übernommen"
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
)}
|
||||||
|
|
||||||
{isFullyBooked ? (
|
{isFullyBooked ? (
|
||||||
<Alert severity="success" icon={<CheckCircleOutlineOutlinedIcon />}>
|
<Alert severity="success" icon={<CheckCircleOutlineOutlinedIcon />}>
|
||||||
Alle Artikel dieser Lieferung sind bereits vollständig im Lager verbucht.
|
Alle Artikel dieser Lieferung sind bereits vollständig im Lager verbucht.
|
||||||
</Alert>
|
</Alert>
|
||||||
) : totalToBook > 0 ? (
|
) : hasTrackStock && totalToBook > 0 ? (
|
||||||
<Alert severity={selectedWarehouseId ? 'info' : 'warning'}>
|
<Alert severity={selectedWarehouseId ? 'info' : 'warning'}>
|
||||||
{selectedWarehouseId ? (
|
{selectedWarehouseId ? (
|
||||||
<>
|
<>
|
||||||
@@ -659,11 +667,11 @@ export default class BookDeliveryDialog extends PureComponent {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</Alert>
|
</Alert>
|
||||||
) : (
|
) : hasTrackStock ? (
|
||||||
<Alert severity="warning">
|
<Alert severity="warning">
|
||||||
Wählen Sie mindestens eine Menge größer als 0 aus, um den Lagerzugang zu buchen.
|
Wählen Sie mindestens eine Menge größer als 0 aus, um den Lagerzugang zu buchen.
|
||||||
</Alert>
|
</Alert>
|
||||||
)}
|
) : null}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ class ManifestFormLine extends PureComponent {
|
|||||||
|
|
||||||
renderLedgerChip() {
|
renderLedgerChip() {
|
||||||
const { ledgerLine, onBookLine } = this.props;
|
const { ledgerLine, onBookLine } = this.props;
|
||||||
if (!ledgerLine) return null;
|
if (!ledgerLine || !ledgerLine.trackStock) return null;
|
||||||
const isBooked = ledgerLine.isBooked;
|
const isBooked = ledgerLine.isBooked;
|
||||||
const isPartial = !isBooked && ledgerLine.bookedAmount > 0;
|
const isPartial = !isBooked && ledgerLine.bookedAmount > 0;
|
||||||
const isClickable = Boolean(onBookLine);
|
const isClickable = Boolean(onBookLine);
|
||||||
|
|||||||
@@ -511,7 +511,7 @@ class ManifestHeader extends PureComponent {
|
|||||||
Wiederherstellen
|
Wiederherstellen
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
{docId != null && kind === 'delivery' && onOpenBookDialog && (
|
{docId != null && kind === 'delivery' && onOpenBookDialog && ledgerSummary?.hasTrackStock && (
|
||||||
<Button
|
<Button
|
||||||
variant={ledgerSummary?.status === 'booked' ? 'outlined' : 'contained'}
|
variant={ledgerSummary?.status === 'booked' ? 'outlined' : 'contained'}
|
||||||
color={
|
color={
|
||||||
|
|||||||
@@ -1234,6 +1234,8 @@ class LieferungNeuPage extends PureComponent {
|
|||||||
}
|
}
|
||||||
allEntries.sort((a, b) => String(b.created_at || '').localeCompare(String(a.created_at || '')));
|
allEntries.sort((a, b) => String(b.created_at || '').localeCompare(String(a.created_at || '')));
|
||||||
|
|
||||||
|
if (!ledgerSummary.hasTrackStock && allEntries.length === 0) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PanelTile
|
<PanelTile
|
||||||
wide={4}
|
wide={4}
|
||||||
@@ -1328,25 +1330,27 @@ class LieferungNeuPage extends PureComponent {
|
|||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Button
|
{ledgerSummary.hasTrackStock && (
|
||||||
variant={status === 'booked' ? 'outlined' : 'contained'}
|
<Button
|
||||||
color={status === 'booked' ? 'success' : status === 'partial' ? 'warning' : 'primary'}
|
variant={status === 'booked' ? 'outlined' : 'contained'}
|
||||||
startIcon={
|
color={status === 'booked' ? 'success' : status === 'partial' ? 'warning' : 'primary'}
|
||||||
status === 'booked' ? (
|
startIcon={
|
||||||
<CheckCircleOutlineOutlinedIcon />
|
status === 'booked' ? (
|
||||||
) : (
|
<CheckCircleOutlineOutlinedIcon />
|
||||||
<Inventory2OutlinedIcon />
|
) : (
|
||||||
)
|
<Inventory2OutlinedIcon />
|
||||||
}
|
)
|
||||||
onClick={this.handleOpenBookDialog}
|
}
|
||||||
sx={{ fontWeight: 600, textTransform: 'none' }}
|
onClick={this.handleOpenBookDialog}
|
||||||
>
|
sx={{ fontWeight: 600, textTransform: 'none' }}
|
||||||
{status === 'booked'
|
>
|
||||||
? 'Buchungsdetails anzeigen'
|
{status === 'booked'
|
||||||
: status === 'partial'
|
? 'Buchungsdetails anzeigen'
|
||||||
? 'Restliche Mengen einbuchen'
|
: status === 'partial'
|
||||||
: 'Ins Lager buchen'}
|
? 'Restliche Mengen einbuchen'
|
||||||
</Button>
|
: 'Ins Lager buchen'}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{allEntries.length > 0 && (
|
{allEntries.length > 0 && (
|
||||||
|
|||||||
@@ -1,5 +1,34 @@
|
|||||||
import { delivery as defaultDeliveryApi, ledger as defaultLedgerApi } from '../api';
|
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
|
* @typedef {Object} DeliveryLineLedgerStatus
|
||||||
@@ -10,6 +39,8 @@ import artikelAutomat from '../automats/artikelAutomat';
|
|||||||
* @property {number} bookedAmount - Quantity booked in ledger
|
* @property {number} bookedAmount - Quantity booked in ledger
|
||||||
* @property {number} remainingAmount - Quantity remaining to be booked
|
* @property {number} remainingAmount - Quantity remaining to be booked
|
||||||
* @property {boolean} isBooked - Whether this position is fully 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<Object>} ledgerEntries - Ledger entries for this line
|
* @property {Array<Object>} ledgerEntries - Ledger entries for this line
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -22,6 +53,7 @@ import artikelAutomat from '../automats/artikelAutomat';
|
|||||||
* @property {number} bookedPositions
|
* @property {number} bookedPositions
|
||||||
* @property {number} totalQuantity
|
* @property {number} totalQuantity
|
||||||
* @property {number} bookedQuantity
|
* @property {number} bookedQuantity
|
||||||
|
* @property {boolean} hasTrackStock
|
||||||
* @property {Array<DeliveryLineLedgerStatus>} lines
|
* @property {Array<DeliveryLineLedgerStatus>} lines
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -48,6 +80,7 @@ export async function fetchDeliveryLedgerSummary(deliveryId, { deliveryApi = def
|
|||||||
bookedPositions: 0,
|
bookedPositions: 0,
|
||||||
totalQuantity: 0,
|
totalQuantity: 0,
|
||||||
bookedQuantity: 0,
|
bookedQuantity: 0,
|
||||||
|
hasTrackStock: false,
|
||||||
lines: [],
|
lines: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -56,20 +89,42 @@ export async function fetchDeliveryLedgerSummary(deliveryId, { deliveryApi = def
|
|||||||
const linesWithLedger = await Promise.all(
|
const linesWithLedger = await Promise.all(
|
||||||
rawLines.map(async (line) => {
|
rawLines.map(async (line) => {
|
||||||
let ledgerEntries = [];
|
let ledgerEntries = [];
|
||||||
try {
|
let article = null;
|
||||||
const ledgerRes = await ledgerApi.listByManifestarticleId(line.id, 'DELIVERY');
|
|
||||||
ledgerEntries = Array.isArray(ledgerRes?.ledger) ? ledgerRes.ledger : [];
|
const promises = [
|
||||||
} catch (err) {
|
ledgerApi.listByManifestarticleId(line.id, 'DELIVERY').catch((err) => {
|
||||||
console.error(`[deliveryLedger] Failed to fetch ledger for line ${line.id}:`, err);
|
console.error(`[deliveryLedger] Failed to fetch ledger for line ${line.id}:`, err);
|
||||||
|
return null;
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
|
||||||
|
if (line.sku) {
|
||||||
|
const cached = getArticle(line.sku);
|
||||||
|
if (cached) {
|
||||||
|
article = cached;
|
||||||
|
} else {
|
||||||
|
promises.push(
|
||||||
|
artikelAutomat.actions.loadArticle(line.sku).catch(() => null)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const results = await Promise.all(promises);
|
||||||
|
const ledgerRes = results[0];
|
||||||
|
if (results[1]) {
|
||||||
|
article = results[1];
|
||||||
|
}
|
||||||
|
ledgerEntries = Array.isArray(ledgerRes?.ledger) ? ledgerRes.ledger : [];
|
||||||
|
|
||||||
|
const trackStock = isLineStockTracked(line, article);
|
||||||
|
|
||||||
const deliveryEntries = ledgerEntries.filter(
|
const deliveryEntries = ledgerEntries.filter(
|
||||||
(e) => String(e.transaction_type).toUpperCase() === 'DELIVERY'
|
(e) => String(e.transaction_type).toUpperCase() === 'DELIVERY'
|
||||||
);
|
);
|
||||||
const bookedAmount = deliveryEntries.reduce((sum, e) => sum + Number(e.amount || 0), 0);
|
const bookedAmount = deliveryEntries.reduce((sum, e) => sum + Number(e.amount || 0), 0);
|
||||||
const targetAmount = Number(line.amount || 0);
|
const targetAmount = Number(line.amount || 0);
|
||||||
const remainingAmount = Math.max(0, targetAmount - bookedAmount);
|
const remainingAmount = trackStock ? Math.max(0, targetAmount - bookedAmount) : 0;
|
||||||
const isBooked = targetAmount > 0 ? bookedAmount >= targetAmount : bookedAmount > 0;
|
const isBooked = trackStock ? (targetAmount > 0 ? bookedAmount >= targetAmount : bookedAmount > 0) : true;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...line,
|
...line,
|
||||||
@@ -77,18 +132,22 @@ export async function fetchDeliveryLedgerSummary(deliveryId, { deliveryApi = def
|
|||||||
bookedAmount,
|
bookedAmount,
|
||||||
remainingAmount,
|
remainingAmount,
|
||||||
isBooked,
|
isBooked,
|
||||||
|
trackStock,
|
||||||
|
isBookable: trackStock,
|
||||||
ledgerEntries: deliveryEntries,
|
ledgerEntries: deliveryEntries,
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
const totalPositions = linesWithLedger.length;
|
const stockLines = linesWithLedger.filter((l) => l.trackStock);
|
||||||
const bookedPositions = linesWithLedger.filter((l) => l.isBooked).length;
|
const totalPositions = stockLines.length;
|
||||||
const totalQuantity = linesWithLedger.reduce((sum, l) => sum + l.targetAmount, 0);
|
const bookedPositions = stockLines.filter((l) => l.isBooked).length;
|
||||||
const bookedQuantity = linesWithLedger.reduce((sum, l) => sum + l.bookedAmount, 0);
|
const totalQuantity = stockLines.reduce((sum, l) => sum + l.targetAmount, 0);
|
||||||
|
const bookedQuantity = stockLines.reduce((sum, l) => sum + l.bookedAmount, 0);
|
||||||
|
const hasTrackStock = stockLines.length > 0;
|
||||||
|
|
||||||
let status;
|
let status;
|
||||||
if (totalPositions === 0) {
|
if (!hasTrackStock) {
|
||||||
status = 'empty';
|
status = 'empty';
|
||||||
} else if (bookedPositions === totalPositions && bookedQuantity >= totalQuantity) {
|
} else if (bookedPositions === totalPositions && bookedQuantity >= totalQuantity) {
|
||||||
status = 'booked';
|
status = 'booked';
|
||||||
@@ -106,6 +165,7 @@ export async function fetchDeliveryLedgerSummary(deliveryId, { deliveryApi = def
|
|||||||
bookedPositions,
|
bookedPositions,
|
||||||
totalQuantity,
|
totalQuantity,
|
||||||
bookedQuantity,
|
bookedQuantity,
|
||||||
|
hasTrackStock,
|
||||||
lines: linesWithLedger,
|
lines: linesWithLedger,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user