u
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { openSession, discardSession, closeSession } from './session.js';
|
||||
import { getOutgoingWarehouse, getWarehousePlace } from './warehouse.js';
|
||||
import { reservePositions } from './reserve.js';
|
||||
import { bookStockShortfallsAndRereserve } from './stock-shortage.js';
|
||||
import { bookStockShortfallsAndRereserve, bookReturnPositions } from './stock-shortage.js';
|
||||
import { commitPicklists } from './commit.js';
|
||||
import { deliverPicklists } from './deliver.js';
|
||||
import { logger } from '../../logger.js';
|
||||
@@ -29,17 +29,28 @@ export async function deliverOrder(transaction, kBenutzer, kAuftrag, kVersandArt
|
||||
const kWarenLager = await getOutgoingWarehouse(transaction);
|
||||
const kWarenLagerPlatz = await getWarehousePlace(transaction, kWarenLager);
|
||||
logger.info(`deliverOrder: kWarenLager=${kWarenLager} kWarenLagerPlatz=${kWarenLagerPlatz}`);
|
||||
|
||||
const positiveItems = deliveredItems.filter((i) => i.quantity > 0);
|
||||
const returnItems = deliveredItems.filter((i) => i.quantity < 0);
|
||||
|
||||
// 1. Process returned items: book them back into warehouse stock via Wareneingang
|
||||
if (returnItems.length) {
|
||||
await bookReturnPositions(transaction, kBenutzer, kWarenLagerPlatz, returnItems);
|
||||
}
|
||||
|
||||
// 2. Process positive items: standard JTL picklist/delivery fulfillment
|
||||
if (positiveItems.length) {
|
||||
const kSessionId = await openSession(transaction, kBenutzer);
|
||||
|
||||
try {
|
||||
await reservePositions(transaction, kBenutzer, kSessionId, kWarenLager, deliveredItems);
|
||||
await reservePositions(transaction, kBenutzer, kSessionId, kWarenLager, positiveItems);
|
||||
await bookStockShortfallsAndRereserve(
|
||||
transaction,
|
||||
kBenutzer,
|
||||
kSessionId,
|
||||
kWarenLager,
|
||||
kWarenLagerPlatz,
|
||||
deliveredItems,
|
||||
positiveItems,
|
||||
);
|
||||
await commitPicklists(transaction, kBenutzer, kSessionId, kAuftrag);
|
||||
await deliverPicklists(transaction, kBenutzer, kSessionId, kAuftrag, kVersandArt);
|
||||
@@ -48,11 +59,6 @@ export async function deliverOrder(transaction, kBenutzer, kAuftrag, kVersandArt
|
||||
logger.error(`deliverOrder: FAILED kAuftrag=${kAuftrag} kSessionId=${kSessionId}: ${err.message}`);
|
||||
throw err;
|
||||
} finally {
|
||||
// Safe to run unconditionally (success or error): spPicklistenVerwerfen only
|
||||
// ever removes not-yet-delivered (nStatus < 10) Picklisten for this session.
|
||||
// Swallow cleanup errors so they never mask an earlier, more relevant error
|
||||
// (the outer transaction rollback in create-order.js is what actually matters
|
||||
// on failure).
|
||||
try {
|
||||
await discardSession(transaction, kBenutzer, kSessionId);
|
||||
await closeSession(transaction, kSessionId);
|
||||
@@ -60,4 +66,5 @@ export async function deliverOrder(transaction, kBenutzer, kAuftrag, kVersandArt
|
||||
// best-effort cleanup only
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ async function getReservedQuantity(transaction, kSessionId, kAuftragPosition) {
|
||||
return reserved;
|
||||
}
|
||||
|
||||
async function getPositionArtikel(transaction, kAuftragPosition) {
|
||||
export async function getPositionArtikel(transaction, kAuftragPosition) {
|
||||
const result = await new sql.Request(transaction)
|
||||
.input('kAuftragPosition', sql.Int, kAuftragPosition)
|
||||
.query(`
|
||||
@@ -35,14 +35,22 @@ async function getPositionArtikel(transaction, kAuftragPosition) {
|
||||
return row?.kArtikel ?? 0;
|
||||
}
|
||||
|
||||
async function bookWareneingang(transaction, kBenutzer, kWarenLagerPlatz, kArtikel, fehlmenge) {
|
||||
export async function bookWareneingang(
|
||||
transaction,
|
||||
kBenutzer,
|
||||
kWarenLagerPlatz,
|
||||
kArtikel,
|
||||
fehlmenge,
|
||||
comment = POS_SHORTAGE_COMMENT,
|
||||
buchungsart = BUCHUNGSART_WARENEINGANG,
|
||||
) {
|
||||
await new sql.Request(transaction)
|
||||
.input('kArtikel', sql.Int, kArtikel)
|
||||
.input('kWarenLagerPlatz', sql.Int, kWarenLagerPlatz)
|
||||
.input('kBenutzer', sql.Int, kBenutzer)
|
||||
.input('fAnzahl', sql.Float, fehlmenge)
|
||||
.input('cKommentar', sql.NVarChar, POS_SHORTAGE_COMMENT)
|
||||
.input('kBuchungsart', sql.Int, BUCHUNGSART_WARENEINGANG)
|
||||
.input('cKommentar', sql.NVarChar, comment)
|
||||
.input('kBuchungsart', sql.Int, buchungsart)
|
||||
.query(`
|
||||
DECLARE @kWarenlagerEingang INT;
|
||||
EXEC dbo.spWarenlagerEingangSchreiben
|
||||
@@ -69,6 +77,37 @@ async function bookWareneingang(transaction, kBenutzer, kWarenLagerPlatz, kArtik
|
||||
`);
|
||||
}
|
||||
|
||||
export async function bookReturnPositions(
|
||||
transaction,
|
||||
kBenutzer,
|
||||
kWarenLagerPlatz,
|
||||
returnPositions,
|
||||
) {
|
||||
logger.info(`returnBooking: processing ${returnPositions.length} return position(s) at kWarenLagerPlatz=${kWarenLagerPlatz}`);
|
||||
for (const { kAuftragPosition, quantity } of returnPositions) {
|
||||
if (!kAuftragPosition || quantity >= 0) {
|
||||
continue;
|
||||
}
|
||||
const returnQty = Math.abs(quantity);
|
||||
const kArtikel = await getPositionArtikel(transaction, kAuftragPosition);
|
||||
logger.info(`returnBooking: kBestellPos=${kAuftragPosition} kArtikel=${kArtikel} returnQty=${returnQty}`);
|
||||
if (!kArtikel) {
|
||||
logger.info(`returnBooking: kBestellPos=${kAuftragPosition} no kArtikel (free position / Pfand?), skip return booking`);
|
||||
continue;
|
||||
}
|
||||
await bookWareneingang(
|
||||
transaction,
|
||||
kBenutzer,
|
||||
kWarenLagerPlatz,
|
||||
kArtikel,
|
||||
returnQty,
|
||||
'Korrekturbuchung erstellt durch POS-Abgleich (Retoure)',
|
||||
BUCHUNGSART_WARENEINGANG,
|
||||
);
|
||||
logger.info(`returnBooking: successfully booked return of ${returnQty}x kArtikel=${kArtikel} into kWarenLagerPlatz=${kWarenLagerPlatz}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* PosStockPositionService.FehlbestandEinbuchen — book missing stock, then re-reserve.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user