Перейти до основного вмісту

Приклад: ідентифікатори в прийманні

Цей приклад проводить одне приймання з вашої системи до WMS і назад і показує кожен вид ідентифікатора дорогою. Самі правила описано у Формуванні payload; тут їх застосовано до справжніх запитів.

Ситуація: у вашій системі є новий товар з кодом prod-0042 і приймання rcpt-2026-0105, яке очікує 24 штуки цього товару. Склад і одиницю «шт» налаштовано у WMS, і ви знаєте їхні ідентифікатори WMS.

Структура приймання — це схема звичайного API: POST /api/v1/inbound/receipts (ReceiptIncomeDto) для того, що ви надсилаєте, GET /api/v1/inbound/receipts/{id} (ReceiptFullResponseDto) для того, що ви читаєте.

1. Надішліть товар і приймання разом​

{
"externalSystemCode": "ERP_MAIN",
"items": [
{
"entityType": "PRODUCT",
"importMode": "UPSERT",
"payload": {
"id": "prod-0042",
"name": "Шоколад 100 г",
"isGroup": false,
"type": "PRODUCT",
"uomId": {"wmsId": "01a16373-d330-729f-80db-29830ee809b9"}
}
},
{
"entityType": "RECEIPT",
"importMode": "UPSERT",
"payload": {
"id": "rcpt-2026-0105",
"status": "TO_RECEIVE",
"date": "2026-10-27",
"warehouseId": {"wmsId": "01a16373-d6be-7746-8eab-fc8e447bfea8"},
"senderContainerHandlingMode": "NOT_USED",
"receivingContainerRequirement": "NONE",
"qcRequired": false,
"allowOverReceiving": false,
"lines": [
{"lineNumber": 1, "productId": "prod-0042", "quantity": 24, "packQuantity": 24}
]
}
}
]
}

Що означає кожен ідентифікатор:

ПолеЗначенняФорма
id товаруprod-0042ваш ідентифікатор товару
uomId товару{"wmsId": "01a16373-d330-…"}ідентифікатор WMS: одиниця існує лише у WMS
id прийманняrcpt-2026-0105ваш ідентифікатор документа
warehouseId приймання{"wmsId": "01a16373-d6be-…"}ідентифікатор WMS: склад існує лише у WMS
lines[0].productIdprod-0042ваш ідентифікатор товару, надісланого раніше в тому самому запиті

Товар іде першим: елементи застосовуються по порядку, і рядок приймання може послатися на товар лише після того, як той з'явився.

2. Прочитайте відповідь​

{
"results": [
{"itemIndex": 0, "entityType": "PRODUCT", "status": "CREATED", "internalEntityId": "01a17a6f-6056-706b-a37c-0eb5fa84eb29", "errors": []},
{"itemIndex": 1, "entityType": "RECEIPT", "status": "CREATED", "internalEntityId": "01a17a6f-60a6-77be-b765-b7e9341d7efe", "errors": []}
]
}

Обидва елементи створено. Відтепер WMS знає, що prod-0042 і rcpt-2026-0105 — ваші: ви можете посилатися на них цими кодами в будь-якому наступному запиті, а зберігати значення internalEntityId не потрібно.

Якби товар не пройшов, не пройшло б і приймання — з помилкою на lines[0].productId: рядок посилається на товар, якого WMS не знає.

// Sends a new product and a receipt of that product in one import request.
// The product is identified by your code; the receipt line refers to it by
// the same code. The warehouse and the unit were set up in the WMS, so they
// are referred to by their WMS identifiers.
async function sendProductAndReceipt({productCode, productName, uomWmsId, receiptCode, warehouseWmsId, date, quantity}) {
const {response, failed} = await importItems([
{
entityType: 'PRODUCT',
importMode: 'UPSERT',
payload: {
id: productCode, // your identifier
name: productName,
isGroup: false,
type: 'PRODUCT',
uomId: {wmsId: uomWmsId}, // a WMS identifier
},
},
{
entityType: 'RECEIPT',
importMode: 'UPSERT',
payload: {
id: receiptCode, // your identifier of the document
status: 'TO_RECEIVE',
date,
warehouseId: {wmsId: warehouseWmsId}, // a WMS identifier
senderContainerHandlingMode: 'NOT_USED',
receivingContainerRequirement: 'NONE',
qcRequired: false,
allowOverReceiving: false,
lines: [
{lineNumber: 1, productId: productCode, quantity, packQuantity: quantity}, // your identifier
],
},
},
]);
if (failed.length > 0) throw new Error('The receipt was not imported');
const [product, receipt] = response.results;
return {productId: product.internalEntityId, receiptId: receipt.internalEntityId};
}

3. Отримайте приймання назад​

Коли приймання змінюється у WMS — товар прийнято, документ підтверджено, — стрічка змін доставляє його поточний стан. Повертаються лише зміни, зроблені у WMS: щойно надіслане вашою системою приймання не повертається відлунням її власного запиту. Частина payload з ідентифікаторами:

{
"id": {"int": "01a17a6f-60a6-77be-b765-b7e9341d7efe", "ext": "rcpt-2026-0105"},
"externalId": "rcpt-2026-0105",
"status": "TO_RECEIVE",
"warehouseId": {"int": "01a16373-d6be-7746-8eab-fc8e447bfea8", "ext": null},
"receivingZoneId": {"int": "01a16373-d73d-7668-89c6-b4e961c83766", "ext": null},
"createdById": {"int": "01a17a4a-af8d-75b2-bafd-7cf085aa6dac", "ext": null},
"executions": [
{
"lineNumber": 1,
"productId": {"int": "01a17a6f-6056-706b-a37c-0eb5fa84eb29", "ext": "prod-0042"},
"quantityPlan": "24.0000",
"quantityExecuted": "0.0000",
"locationId": {"int": "01a16373-d73d-7668-89c6-b4e961c83766", "ext": null}
}
]
}
  • id.ext і executions[].productId.ext містять ваші коди: за ними знаходьте документ і товар у своїй системі.
  • warehouseId.ext дорівнює null: ваша система ніколи не надсилала цей склад. Зіставляйте його за int, який ви передавали в {"wmsId": …}.
  • receivingZoneId не було у вашому запиті: WMS заповнила його з налаштувань складу. Його ext теж null.
  • createdById — користувач WMS. Користувачі ніколи не мають ext.
  • Кількості — десяткові числа в рядках. Перетворюйте їх на десятковий тип.
  • Рядки приймання повертаються в executions із запланованою та прийнятою кількістю кожного рядка.
// Turns a receipt payload from the change feed into what your system needs.
// Every identifier is a pair: `int` is the WMS identifier, `ext` is yours
// (null when the record did not come from your system).
function readReceipt(payload) {
return {
wmsId: payload.id.int,
externalId: payload.id.ext, // the `id` you sent, in lower case
status: payload.status,
warehouse: payload.warehouseId,
createdBy: payload.createdById, // a WMS user: `ext` is always null
lines: payload.executions.map((line) => ({
lineNumber: line.lineNumber,
product: line.productId,
planned: Number(line.quantityPlan),
received: Number(line.quantityExecuted),
})),
};
}

// Finds your record by your identifier, or by a WMS identifier you stored before.
function findLocalRecord(ref, localByCode, localByWmsId) {
return (ref.ext && localByCode.get(ref.ext)) ?? localByWmsId.get(ref.int);
}

// Usage with the change feed:
// await pollChangeFeed(async (event, payload) => {
// if (event.entityType !== 'RECEIPT') return; // other types are handled elsewhere
// const receipt = readReceipt(payload);
// for (const line of receipt.lines) {
// const product = findLocalRecord(line.product, productsByCode, productsByWmsId);
// // ... update the received quantity of `product` in your document `receipt.externalId`
// }
// });