Aiden WMS

Purchase Order

TL;DR — Aiden WMS Purchase Order Mapper (Outbound)
  • Purpose: Create a WMS receipt expectation (IncomingDocument) from an open SAP B1 Purchase Order, including only the lines relevant for warehouse receiving.

  • Flow & Correlation: B1 PO JSON on Kafka → mapper builds WMS IncomingDocument with baseType=PurchaseOrder and customFields.objectType=PurchaseOrders → publishes to WMS → correlation.correlationId comes from the Kafka message key for tracing.

  • Inputs:

    • Main payload: B1 PO header (DocNum/DocEntry, CardCode/Name, DocDueDate, DocumentStatus, NumAtCard), lines (ItemCode, WarehouseCode, LineStatus, RemainingOpenQuantity, UoM fields, FreeText, line expenses), header expenses.

    • Per-message enrichment: Items lookup ($select=ItemCode,InventoryItem) in batches (default 20).

    • Hourly master: Warehouses with U_AEN_WHS_Picking flag.

  • Which lines are included: Only lines where the item is an inventory item (InventoryItem=tYES) AND the line’s warehouse has U_AEN_WHS_Picking=Y. Others are dropped.

  • Quantities: lines[].quantity = RemainingOpenQuantity (not original ordered Quantity). Closed lines can appear with quantity 0 if they pass filters.

  • Statuses:

    • Header: data.status = DocumentStatus without “bost_” (e.g., bost_Open → Open).

    • Lines: lines[].status = LineStatus without “bost_” and “Close” normalized to “Closed”.

  • UoM per line (uomCode):

    • If UoMEntry != -1 → use UoMCode.

    • If UoMEntry = -1 (manual) → use "m" + MeasureUnit (e.g., mPallet); empty MeasureUnit → "m".

  • Dates & partner:

    • data.receiveDate = DocDueDate.

    • Vendor mapped from CardCode/CardName.

  • References & expenses:

    • NumAtCard becomes a dynamic custom property (name “NumAtCard”).

    • Header and line additional expenses are copied into data.customFields.DocumentAdditionalExpenses and lines[].customFields.DocumentAdditionalExpenses respectively (ExpenseCode, LineTotal, GroupCode, DistributionMethod, VatGroup, LineNum).

  • Not covered / caveats: Non-inventory items and non-picking warehouses are excluded; ordered Quantity isn’t mapped; financials beyond the mapped expenses, addresses, and owner are out of scope; large POs trigger batched item enrichment calls.

  • E2E expectation: PO published → warehouses preloaded, items enriched → mapper filters lines and sets open quantities → publishes IncomingDocument → trace with correlation.correlationId and DocEntry/DocNum.

  • Consultant checklist: Mark stock items as Inventory Item; set U_AEN_WHS_Picking=Y on intended warehouses; align on RemainingOpenQuantity semantics; maintain UoM entries and understand manual (-1) fallback; expect non-inventory (service) lines to be excluded; after partial receipts, republished POs show reduced open quantities.

Functional documentation for the Aiden WMS purchase order mapper (outbound).

This document describes what happens after the mapper is installed: how a SAP Business One (B1) purchase order becomes a WMS incoming/receipt document, which lines are included, and which field rules apply. It is intended for end-users and functional consultants.


1. Overview



Source

SAP B1 Purchase Order (Service Layer document JSON on Kafka)

Target

Aiden WMS Incoming document (IncomingDocument)

Purpose

Create a WMS receipt expectation from an open B1 purchase order

After installation, when a purchase order is published to the integration, the mapper produces a WMS document that contains:

  • Document identity and base type PurchaseOrder

  • Vendor (business partner)

  • Receive date

  • Filtered order lines (inventory items on picking warehouses only)

  • Remaining open quantities

  • Optional expenses and customer reference (NumAtCard)

  • Correlation id for tracking

Fixed business defaults

WMS field

Fixed value

Meaning

data.baseType

PurchaseOrder

Document originates from a purchase order

data.customFields.objectType

PurchaseOrders

Object type label for downstream WMS/integration


2. What the mapper uses as input

2.1 Main payload — B1 purchase order

The primary input is the B1 purchase order document, including for example:

  • Header: DocNum, DocEntry, CardCode, CardName, DocDueDate, DocumentStatus, NumAtCard

  • Lines: DocumentLines[] (LineNum, ItemCode, WarehouseCode, LineStatus, RemainingOpenQuantity, UoM fields, FreeText, line expenses)

  • Header expenses: DocumentAdditionalExpenses[]

DocNum is also used as the integration external application id for monitoring.

2.2 Inventory item enrichment (automatic, per message)

Before mapping, the integration calls B1 Items for every distinct line item code on the PO:

  • $select=ItemCode,InventoryItem

  • Requests are batched (max.items.from.service.layer, default 20 item codes per call)

Business impact: only lines whose item is an inventory item (InventoryItem = tYES) are sent to WMS. Non-inventory items (services, non-stock, etc.) are dropped.

2.3 Warehouse list (automatic, hourly)

The integration periodically loads warehouses from B1:

  • WarehouseCode

  • U_AEN_WHS_Picking (Y / N)

  • (also retrieved: EnableBinLocations, DefaultBin — not used as primary line filter in this mapping)

Business impact: only lines whose warehouse is marked picking-enabled (U_AEN_WHS_Picking = Y) are sent to WMS.

2.4 Correlation id

Integration message key → correlation.correlationId.


3. Business behavior

3.1 Which lines are sent to WMS?

A B1 PO line is included in data.lines only when both are true:

  1. Enriched item master has InventoryItem = tYES for that ItemCode

  2. Line WarehouseCode matches a warehouse with U_AEN_WHS_Picking = Y

Otherwise the line is omitted.

Configure inventory flags on items and picking warehouses in B1 before go-live. Otherwise receipts may miss lines or include none.

3.2 Quantity = remaining open quantity

WMS line quantity is mapped from B1 RemainingOpenQuantity, not from the original ordered Quantity.

Situation

Effect in WMS

Fully open line

Open qty ≈ ordered qty

Partially received in B1

Only remaining open qty is expected in WMS

Fully closed / fully received (RemainingOpenQuantity = 0)

Line can still appear (if filters pass) with quantity 0 and closed status

This is critical for consultants: the mapper is aimed at what is still open to receive, not the original PO quantity.

3.3 Document and line status

B1 statuses look like bost_Open / bost_Close.

Level

B1 field

Transformation

WMS field

Header

DocumentStatus

Strip prefix bost_

data.status (e.g. Open)

Line

LineStatus

Strip bost_, then CloseClosed

lines[].status

B1 line value

WMS line status

bost_Open

Open

bost_Close

Closed

Header status strip does not apply the Close→Closed valuemap in the same way as lines; header typically becomes Open / Close after removing bost_.

3.4 Unit of measure (uomCode)

For each included line:

  1. If UoMEntry is not -1 → use UoMCode

  2. If UoMEntry is -1 → use "m" + MeasureUnit

    • Missing MeasureUnit is substituted with empty → result can be just m

Examples from scenario-style data: manual UoM (UoMEntry = -1) with MeasureUnit = PalletmPallet; empty measure → m.

3.5 Receive date

data.receiveDateDocDueDate (PO due date becomes expected receive date in WMS).

3.6 Customer / vendor reference (NumAtCard)

If filled, NumAtCard is exposed as a dynamic custom property:

  • Property name: NumAtCard

  • Property value: B1 NumAtCard

3.7 Additional expenses

  • Header DocumentAdditionalExpensesdata.customFields.DocumentAdditionalExpenses[]

  • Line DocumentLineAdditionalExpenseslines[].customFields.DocumentAdditionalExpenses[]

Copied fields include ExpenseCode, LineTotal, GroupCode, DistributionMethod, VatGroup, LineNum.


4. Field mapping tables

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

4.1 Correlation

WMS output field

B1 / source input

What happens

Notes

correlation.correlationId

Integration message key

Direct

Tracing

4.2 Document header (data)

WMS output field

B1 / source input

What happens

Notes

data.documentId

DocNum

Direct


data.baseType

Constant PurchaseOrder

Always

data.receiveDate

DocDueDate

Direct

Expected receive date

data.status

DocumentStatus

Strip bost_

e.g. bost_OpenOpen

data.details

(if mapped / empty in samples)

Often empty unless source has remarks wired

Check MFD if comments are required

data.customFields.externalId

DocEntry

Direct

Internal B1 key

data.customFields.objectType

Constant PurchaseOrders

Always

Dynamic property NumAtCard

NumAtCard

Name constant + value

When filled in B1

4.3 Business partner

WMS output field

B1 / source input

What happens

Notes

data.businessPartner.businessPartnerId

CardCode

Direct

Vendor

data.businessPartner.name

CardName

Direct


4.4 Lines (data.lines[])

Only lines that pass inventory item + picking warehouse filters (§3.1).

WMS output field

B1 / source input

What happens

Notes

lines[].documentLine

DocumentLines.LineNum

Direct


lines[].warehouseId

DocumentLines.WarehouseCode

Direct

Must be picking-enabled

lines[].itemId

DocumentLines.ItemCode

Direct

Must be inventory item

lines[].quantity

DocumentLines.RemainingOpenQuantity

Direct

Not ordered Quantity

lines[].uomCode

UoMEntry, UoMCode, MeasureUnit

Conditional — see §3.4


lines[].status

DocumentLines.LineStatus

Strip bost_ + CloseClosed


lines[].details

DocumentLines.FreeText

Direct


lines[].customFields.lineNum

DocumentLines.LineNum

Direct

Same as document line

lines[].receiveDate

(schema may allow; not always wired)

Primary receive date is header

4.5 Expenses

WMS output field

B1 / source input

What happens

Notes

data.customFields.DocumentAdditionalExpenses.*

Header expenses

Direct field copy

ExpenseCode, LineTotal, GroupCode, DistributionMethod, VatGroup, LineNum

lines[].customFields.DocumentAdditionalExpenses.*

Line expenses

Direct field copy

Same structure


5. Value translations (reference)

5.1 Status

B1

After processing

bost_Open

Header: Open / Line: Open

bost_Close

Header: Close (prefix strip) / Line: Closed (prefix strip + valuemap)

5.2 Warehouse picking

U_AEN_WHS_Picking

Line included?

Y

Yes (if also inventory item)

N

No

5.3 Inventory item enrichment

B1 InventoryItem

Line included?

tYES

Yes (if also picking warehouse)

tNO

No

5.4 Constants

Constant

WMS usage

PurchaseOrder

data.baseType

PurchaseOrders

customFields.objectType

NumAtCard

Dynamic property name

m / -1

UoM fallback building blocks


6. What is not mapped / caveats

Topic

Behavior

Non-inventory items

Excluded via Items enrichment

Non-picking warehouses

Excluded via warehouse master

Ordered quantity

Not mapped; open qty is used

Prices, VAT, freight as financials

Only expense structures that are explicitly mapped

Bill-to / full address block

Not part of this receipt schema mapping

owner

Null / unused in samples

Batch size for item GET

Default 20 codes per Service Layer call; large POs are chunked


7. Example (scenario 1_PurchaseOrder)

B1 input (excerpt)

Field

Example

DocNum / DocEntry

547

CardCode / CardName

V21000 / Meer B.V.

DocDueDate

2024-11-28T00:00:00Z

DocumentStatus

bost_Open

Lines

A00001, A00002, A00006, B10000 on WH 01, all bost_Close, RemainingOpenQuantity = 0

Items enrichment

A00006 has InventoryItem = tNO; others tYES

WMS output (excerpt from 3_target.json)

WMS field

Example result

data.documentId

547 (from DocNum; scenario file 3_target.json shows PO-547 and may be outdated vs current MFD)

BP

V21000 / Meer B.V.

receiveDate

2024-11-28T00:00:00Z

status

Open

customFields.externalId

547

customFields.objectType

PurchaseOrders

Lines included

Inventory items only — A00006 omitted

Line quantities

0 (remaining open)

Line status

Close/Closed style from closed B1 lines

uomCode

m or mPallet for manual UoM entries

Use this scenario to validate filters + open qty, not a happy-path open receipt with positive quantities.


8. End-to-end expectation (happy path)

  1. Purchase order is created/updated in B1 and published to Kafka.

  2. Integration loads picking warehouses (timer) and, per message, enriches line items with InventoryItem.

  3. Mapper builds WMS incoming document:

    • Header + vendor + due date

    • Only inventory lines on picking warehouses

    • Quantities = remaining open

  4. Message is published for WMS IncomingDocument.

  5. Trace with correlation.correlationId and customFields.externalId (DocEntry).


9. Implementation checklist for consultants

  1. Mark stock items as Inventory Item in B1.

  2. Set U_AEN_WHS_Picking = Y on warehouses that must create WMS receipt work.

  3. Understand that WMS quantity is remaining open, not ordered qty.

  4. Maintain UoM entries; know the -1 / manual fallback (m + measure unit).

  5. Expect non-inventory PO lines (freight service items, etc.) not to appear in WMS.

  6. After partial GRPO in B1, republished POs should show reduced open quantities.

  7. Trace with correlation id + DocEntry / DocNum.


10. Source artifacts

Artifact

Role

mappings/purchase-order/purchase-order-mapper.mfd

MapForce mapping

mappings/purchase-order/input_purchase_order.schema.json

B1 PO schema

mappings/purchase-order/output_receipt_document.schema.json

WMS receipt schema

mappings/purchase-order/intermediate.warehouses.schema.json

Warehouse list

mappings/purchase-order/enrich_INVENTORYITEMS_Schema.json

Item enrichment schema

src/.../route/MainRoutes.java

Kafka in/out, IncomingDocument

src/.../route/EnrichInventoryItemsRoute.java

Items GET batch enrichment

src/.../route/ConfigurationRoute.java

Warehouse timer load

src/.../mapper/Mapper.java

MapForce runner

scenario_files/1_PurchaseOrder/

Sample PO → target


Generated from the mapping definition and integration behavior in this project. If the MapForce mapping or enrichment rules change, 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.