Aiden WMS

Inventory (Stock Corrections)

TL;DR — Aiden WMS Inventory Mapper (Inbound)
  • Purpose: Convert WMS inventory adjustments (stock in/out) into SAP B1 Inventory Gen. Entry/Exit via Service Layer, including reason-to-account mapping, batches/serials, and traceability.

  • Routing by transaction.type:

    • InventoryInbound → post InventoryGenEntries (Goods Receipt).

    • Anything else (e.g., InventoryOutbound) → post InventoryGenExits (Goods Issue).

    • Always POST.

  • Inputs used:

    • transaction.id (traceability), transaction.type (direction), documents[].documentId (UDF), documents[].reason.* (account + comments), lines[] (item, warehouse, qty, optional batch/serial, optional numPerUom).

    • No warehouse master or item enrichment required.

  • Key behaviors:

    • Quantity to B1 base units: Quantity = quantity × numPerUom. Send a reliable numPerUom (often 1 if already base UoM).

    • Reason → AccountCode valuemap:

      • IR1 → 3100 (stock in).

      • OR1 → 3200 (stock out).

      • Unmapped or "null" → empty account (no override).

    • Traceability:

      • Header comments = reason.reasonDesc.

      • U_AEN_WMS_TRANSID = documents[].documentId (WMS doc/transaction ref).

      • Use with transaction.id for reconciliation.

  • Lines mapping (core):

    • DocumentLines: LineNum ← lines.documentLine; ItemCode ← lines.itemId; WarehouseCode ← lines.warehouseId; Quantity ← lines.quantity × lines.numPerUom; AccountCode from reasonId valuemap.

    • Batches (when batchNumber non-empty): BatchNumber, ExpiryDate, BaseLineNumber, Quantity = quantity × numPerUom.

    • Serials (when serialNumber non-empty): InternalSerialNumber, ManufacturerSerialNumber (same), BaseLineNumber, Quantity = quantity × numPerUom.

    • Note: serialNumberOutbound is not wired; outbound must also populate serialNumber.

  • Not covered / caveats:

    • No bin allocations, license/carrier, prices/BP/base docs, or PaymentGroupCode.

    • If numPerUom is missing/0, resulting line quantities may be incorrect—WMS should send it explicitly.

    • Multi-document payloads: mapping follows modeled document/line structure; validate if sending more than one doc.

  • End-to-end expectation:

    • WMS posts inventory movement → Kafka → mapper selects Gen. Entry or Exit → builds B1 JSON (comments, UDF, lines, optional batch/serial, account from reason) → POST to B1 → trace via Kafka key, transaction.id, and U_AEN_WMS_TRANSID.

  • Consultant checklist:

    • Ensure correct transaction.type (Inbound vs Outbound).

    • Align reason codes with G/L accounts (IR1→3100, OR1→3200) or extend mapping for local codes (e.g., IR2).

    • Provide numPerUom so B1 receives base-unit quantities.

    • For batches, include batchNumber (and expiry if required).

    • For serials (including outbound), populate serialNumber.

    • Verify accounts (e.g., 3100/3200) exist and are permitted on Inventory Gen documents.

Functional documentation for the Aiden WMS inventory mapper (inbound).

This document describes what happens after the mapper is installed: how a WMS inventory adjustment (stock in or stock out) becomes a SAP Business One (B1) inventory document, which fields are mapped, and which business rules apply. It is intended for end-users and functional consultants.


1. Overview



Source

Aiden WMS inventory transaction (Kafka)

Target

SAP B1 inventory document via Service Layer (Kafka → B1)

Purpose

Post stock corrections / free inventory movements from WMS into B1

After installation, when WMS completes an inventory inbound or outbound movement, the mapper produces a B1 document with:

  • Transaction reference (U_AEN_WMS_TRANSID)

  • Comments from the WMS reason description

  • Document lines (item, warehouse, quantity in base units)

  • Optional batch and/or serial sub-lines

  • G/L account derived from the WMS reason code (when configured)

Inbound vs outbound (routing)

WMS transaction.type

B1 document posted

Endpoint header

InventoryInbound

Inventory Goods Receipt (stock in)

InventoryGenEntries

Anything else (e.g. InventoryOutbound)

Inventory Goods Issue (stock out)

InventoryGenExits

HTTP method is always POST.


2. What the mapper uses as input

2.1 WMS inventory message

Typical structure:

  • transaction.id — WMS transaction id (also used as integration external application id)

  • transaction.typeInventoryInbound or InventoryOutbound (drives B1 document type)

  • documents[]:

    • documentId — becomes B1 UDF transaction id

    • reason.reasonId / reason.reasonDesc — account mapping + comments

    • lines[] — item, warehouse, quantity, optional batch/serial, optional numPerUom

No separate warehouse master load or item enrichment is required for this mapper (unlike some other Aiden flows).

2.2 Correlation / monitoring

Value

Source

Use

Integration message id

Kafka key

XIAM correlation

External application id

transaction.id

XIAM

Message type

InventoryInbound or InventoryOutbound

XIAM message type


3. Business behavior

3.1 Document type selection

Only transaction.type == InventoryInbound posts an Inventory Gen. Entry.
All other types (including InventoryOutbound) post an Inventory Gen. Exit.

Consultants must set the correct transaction type in WMS so stock goes the right direction in B1.

3.2 Quantity and unit of measure

B1 line Quantity is calculated as:

Quantity = quantity × numPerUom

WMS fields

Meaning

quantity

Quantity in the UoM used on the line

numPerUom

How many base/inventory units per that UoM

If numPerUom is missing or not sent, behavior depends on runtime data (schema allows integer; mapping multiplies the two fields). For correct stock, WMS should send a reliable factor (often 1 when already in base UoM).

3.3 Reason → G/L account (AccountCode)

WMS documents[].reason.reasonId is translated to a B1 G/L AccountCode:

WMS reasonId

B1 AccountCode

Typical meaning

IR1

3100

Inbound / stock correction in

OR1

3200

Outbound / stock correction out

Other / unmapped

No mapped account (null/empty path)

Extend valuemap if more reasons are needed

Reason id string "null"

Forced empty/null account branch

Defensive handling in mapping

Comments on the B1 document is filled from reason.reasonDesc (human-readable reason text).

3.4 Batches

If lines[].batchNumber is non-empty, a batch sub-structure is created on the B1 line:

B1 batch field

WMS source

BatchNumber

batchNumber

ExpiryDate

expiryDate

BaseLineNumber

documentLine

Quantity

quantity × numPerUom

If batchNumber is empty, no batch block is emitted for that line.

3.5 Serials

If lines[].serialNumber is non-empty, a serial sub-structure is created:

B1 serial field

WMS source

InternalSerialNumber

serialNumber

ManufacturerSerialNumber

serialNumber (same value)

BaseLineNumber

documentLine

Quantity

quantity × numPerUom

If serialNumber is empty, no serial block is emitted.

Important: some WMS outbound examples also carry serialNumberOutbound. The current MapForce mapping wires serialNumber only. For outbound serial stock corrections, ensure the serial is present in serialNumber (or extend the mapping if outbound-only fields must be used).

3.6 Transaction traceability

B1 field

WMS source

U_AEN_WMS_TRANSID

documents[].documentId

Use this UDF together with transaction.id for support and reconciliation.


4. Field mapping tables

Columns: B1 target field | WMS / source input | What happens | Notes

4.1 Header

B1 target field

WMS / source input

What happens

Notes

Comments

documents[].reason.reasonDesc

Direct

Reason description

U_AEN_WMS_TRANSID

documents[].documentId

Direct

WMS document/transaction reference

PaymentGroupCode

Not mapped

Present in output schema only

4.2 Document lines

B1 target field

WMS / source input

What happens

Notes

DocumentLines[].LineNum

lines[].documentLine

Direct


DocumentLines[].ItemCode

lines[].itemId

Direct


DocumentLines[].WarehouseCode

lines[].warehouseId

Direct


DocumentLines[].Quantity

lines[].quantity, lines[].numPerUom

Multiply

Base units

DocumentLines[].AccountCode

documents[].reason.reasonId

Valuemap + if-else

See §3.3

4.3 Batches (conditional)

B1 target field

WMS / source input

What happens

Notes

Batch block present?

batchNumber non-empty

Filter

Empty batch → no block

BatchNumbers[].BatchNumber

batchNumber

Direct


BatchNumbers[].ExpiryDate

expiryDate

Direct


BatchNumbers[].BaseLineNumber

documentLine

Direct


BatchNumbers[].Quantity

quantity × numPerUom

Multiply

Same as line qty

4.4 Serials (conditional)

B1 target field

WMS / source input

What happens

Notes

Serial block present?

serialNumber non-empty

Filter

Empty serial → no block

SerialNumbers[].InternalSerialNumber

serialNumber

Direct


SerialNumbers[].ManufacturerSerialNumber

serialNumber

Direct

Same value

SerialNumbers[].BaseLineNumber

documentLine

Direct


SerialNumbers[].Quantity

quantity × numPerUom

Multiply



5. Value translations (reference)

5.1 Transaction type → B1 endpoint

WMS transaction.type

B1 endpoint

InventoryInbound

InventoryGenEntries

Other (e.g. InventoryOutbound)

InventoryGenExits

5.2 Reason id → account

reason.reasonId

AccountCode

IR1

3100

OR1

3200

Unmapped

Empty/null account path


6. What is not mapped / caveats

Topic

Behavior

Bin location (binId)

Not mapped to B1 line/bin allocations in this MFD

License / carrier

Not mapped

Item name

Not mapped (B1 uses item master)

PaymentGroupCode

In schema; not wired

serialNumberOutbound

Not wired; use serialNumber

Prices / BP / base documents

Not applicable to free inventory gen docs in this flow

Multi-document payloads

Mapping focuses on document/line structure as modeled; validate multi-doc if used


7. Example

WMS input (scenario 1_mainRoute excerpt)

Field

Example

transaction.type

InventoryInbound → posts InventoryGenEntries

transaction.id

IN-2026012700059

documentId

IN-2026012700059

reason.reasonId / reasonDesc

IR2 / Voorraad Opboeking

Line

Item A00001, WH 05, qty 3

Expected B1 shape (from mapping rules)

B1 field

Expected

Endpoint

InventoryGenEntries

Comments

Voorraad Opboeking

U_AEN_WMS_TRANSID

IN-2026012700059

Line ItemCode / WarehouseCode

A00001 / 05

Line Quantity

3 × numPerUom (if numPerUom empty/0, verify runtime)

Line AccountCode

Unmapped for IR2 unless valuemap is extended (only IR1/OR1 are defined)

Outbound serial example (mapping sample)

inputExample.json uses transaction.type = InventoryOutbound and serialNumberOutbound.
With the current MFD, serials are only taken from serialNumber. Ensure outbound processes populate serialNumber, or the B1 exit will not carry serials.


8. End-to-end expectation

  1. User posts an inventory inbound or outbound movement in WMS (with reason).

  2. WMS publishes the inventory transaction to Kafka.

  3. Integration chooses Inventory Gen. Entry or Exit from transaction.type.

  4. Mapper builds B1 JSON (comments, UDF, lines, batches/serials, account from reason).

  5. Message is sent for B1 POST.

  6. Trace with Kafka key, transaction.id, and U_AEN_WMS_TRANSID (documentId).


9. Implementation checklist for consultants

  1. Align WMS reason codes with the account valuemap (IR1→3100, OR1→3200) or request mapping extensions for additional codes (e.g. IR2).

  2. Use correct transaction.type so stock increases vs decreases in B1.

  3. Send reliable numPerUom so B1 quantity is in inventory base units.

  4. For batch items, fill batchNumber (and expiry if required).

  5. For serial items, fill serialNumber (including outbound corrections).

  6. Confirm B1 G/L accounts 3100 / 3200 (or your local equivalents after remap) exist and are allowed on inventory gen docs.

  7. Use U_AEN_WMS_TRANSID / transaction.id for reconciliation.


10. Source artifacts

Artifact

Role

mappings/inventory-mapper.mfd

MapForce mapping

mappings/inventory-mapper.mfp

MapForce project

mappings/inputSchema.json / inputExample.json

WMS input contract / sample

mappings/outputSchema.json

B1 output contract

src/.../route/MainRoutes.java

Inbound/outbound endpoint routing

src/.../mapper/Mapper.java

MapForce runner

scenario_files/1_mainRoute/

Sample source (target file may be incomplete)


Generated from the mapping definition and integration routes in this project. If the MapForce mapping or routing changes, update this document.


Maintaining this document

For the original documentation intent, when to update, source-of-truth checklist, and a ready-made refresh prompt, see README.md and the repository AGENTS.md.