u
This commit is contained in:
@@ -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<Object>} ledgerEntries - Ledger entries for this line
|
||||
*/
|
||||
|
||||
@@ -22,6 +53,7 @@ import artikelAutomat from '../automats/artikelAutomat';
|
||||
* @property {number} bookedPositions
|
||||
* @property {number} totalQuantity
|
||||
* @property {number} bookedQuantity
|
||||
* @property {boolean} hasTrackStock
|
||||
* @property {Array<DeliveryLineLedgerStatus>} lines
|
||||
*/
|
||||
|
||||
@@ -48,6 +80,7 @@ export async function fetchDeliveryLedgerSummary(deliveryId, { deliveryApi = def
|
||||
bookedPositions: 0,
|
||||
totalQuantity: 0,
|
||||
bookedQuantity: 0,
|
||||
hasTrackStock: false,
|
||||
lines: [],
|
||||
};
|
||||
}
|
||||
@@ -56,20 +89,42 @@ export async function fetchDeliveryLedgerSummary(deliveryId, { deliveryApi = def
|
||||
const linesWithLedger = await Promise.all(
|
||||
rawLines.map(async (line) => {
|
||||
let ledgerEntries = [];
|
||||
try {
|
||||
const ledgerRes = await ledgerApi.listByManifestarticleId(line.id, 'DELIVERY');
|
||||
ledgerEntries = Array.isArray(ledgerRes?.ledger) ? ledgerRes.ledger : [];
|
||||
} catch (err) {
|
||||
console.error(`[deliveryLedger] Failed to fetch ledger for line ${line.id}:`, err);
|
||||
let article = null;
|
||||
|
||||
const promises = [
|
||||
ledgerApi.listByManifestarticleId(line.id, 'DELIVERY').catch((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(
|
||||
(e) => String(e.transaction_type).toUpperCase() === 'DELIVERY'
|
||||
);
|
||||
const bookedAmount = deliveryEntries.reduce((sum, e) => sum + Number(e.amount || 0), 0);
|
||||
const targetAmount = Number(line.amount || 0);
|
||||
const remainingAmount = Math.max(0, targetAmount - bookedAmount);
|
||||
const isBooked = targetAmount > 0 ? bookedAmount >= targetAmount : bookedAmount > 0;
|
||||
const remainingAmount = trackStock ? Math.max(0, targetAmount - bookedAmount) : 0;
|
||||
const isBooked = trackStock ? (targetAmount > 0 ? bookedAmount >= targetAmount : bookedAmount > 0) : true;
|
||||
|
||||
return {
|
||||
...line,
|
||||
@@ -77,18 +132,22 @@ export async function fetchDeliveryLedgerSummary(deliveryId, { deliveryApi = def
|
||||
bookedAmount,
|
||||
remainingAmount,
|
||||
isBooked,
|
||||
trackStock,
|
||||
isBookable: trackStock,
|
||||
ledgerEntries: deliveryEntries,
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
const totalPositions = linesWithLedger.length;
|
||||
const bookedPositions = linesWithLedger.filter((l) => l.isBooked).length;
|
||||
const totalQuantity = linesWithLedger.reduce((sum, l) => sum + l.targetAmount, 0);
|
||||
const bookedQuantity = linesWithLedger.reduce((sum, l) => sum + l.bookedAmount, 0);
|
||||
const stockLines = linesWithLedger.filter((l) => l.trackStock);
|
||||
const totalPositions = stockLines.length;
|
||||
const bookedPositions = stockLines.filter((l) => l.isBooked).length;
|
||||
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;
|
||||
if (totalPositions === 0) {
|
||||
if (!hasTrackStock) {
|
||||
status = 'empty';
|
||||
} else if (bookedPositions === totalPositions && bookedQuantity >= totalQuantity) {
|
||||
status = 'booked';
|
||||
@@ -106,6 +165,7 @@ export async function fetchDeliveryLedgerSummary(deliveryId, { deliveryApi = def
|
||||
bookedPositions,
|
||||
totalQuantity,
|
||||
bookedQuantity,
|
||||
hasTrackStock,
|
||||
lines: linesWithLedger,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user