Example: identifiers in a receipt
This example follows one receipt from your system into the WMS and back, and shows every kind of identifier on the way. The rules themselves are on Building the payload; here they are applied to real requests.
The situation: your system has a new product, code prod-0042, and a receipt rcpt-2026-0105 that expects 24 pieces of it. The warehouse and the unit "pcs" were set up in the WMS, and you know their WMS identifiers.
The structure of a receipt is the schema of the regular API: POST /api/v1/inbound/receipts (ReceiptIncomeDto) for what you send, GET /api/v1/inbound/receipts/{id} (ReceiptFullResponseDto) for what you read.
1. Send the product and the receipt together
{
"externalSystemCode": "ERP_MAIN",
"items": [
{
"entityType": "PRODUCT",
"importMode": "UPSERT",
"payload": {
"id": "prod-0042",
"name": "Chocolate 100 g",
"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}
]
}
}
]
}
What each identifier is:
| Field | Value | Form |
|---|---|---|
product id | prod-0042 | your identifier of the product |
product uomId | {"wmsId": "01a16373-d330-…"} | a WMS identifier: the unit exists only in the WMS |
receipt id | rcpt-2026-0105 | your identifier of the document |
receipt warehouseId | {"wmsId": "01a16373-d6be-…"} | a WMS identifier: the warehouse exists only in the WMS |
lines[0].productId | prod-0042 | your identifier of the product sent earlier in the same request |
The product goes first: items are applied in order, and the receipt line can refer to the product only after it exists.
2. Read the answer
{
"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": []}
]
}
Both items were created. From now on the WMS knows that prod-0042 and rcpt-2026-0105 are yours: you can refer to them by these codes in any later request, and you do not need to store the internalEntityId values.
Had the product failed, the receipt would fail too, with an error on lines[0].productId — the line refers to a product the WMS does not know.
- JavaScript
- Python
- 1C
// 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};
}
def send_product_and_receipt(*, product_code, product_name, uom_wms_id, receipt_code,
warehouse_wms_id, date, quantity):
"""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."""
response, failed = import_items([
{
"entityType": "PRODUCT",
"importMode": "UPSERT",
"payload": {
"id": product_code, # your identifier
"name": product_name,
"isGroup": False,
"type": "PRODUCT",
"uomId": {"wmsId": uom_wms_id}, # a WMS identifier
},
},
{
"entityType": "RECEIPT",
"importMode": "UPSERT",
"payload": {
"id": receipt_code, # your identifier of the document
"status": "TO_RECEIVE",
"date": date,
"warehouseId": {"wmsId": warehouse_wms_id}, # a WMS identifier
"senderContainerHandlingMode": "NOT_USED",
"receivingContainerRequirement": "NONE",
"qcRequired": False,
"allowOverReceiving": False,
"lines": [
# productId: your identifier
{"lineNumber": 1, "productId": product_code, "quantity": quantity, "packQuantity": quantity},
],
},
},
])
if failed:
raise RuntimeError("The receipt was not imported")
product, receipt = response["results"]
return {"product_id": product["internalEntityId"], "receipt_id": receipt["internalEntityId"]}
// 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. Returns Структура(Товар, Приемка) with WMS identifiers.
Функция ОтправитьТоварИПриемку(Подключение, КодТовара, НаименованиеТовара, ИдЕдиницыWMS,
КодПриемки, ИдСкладаWMS, Дата, Количество) Экспорт
Товар = Новый Структура;
Товар.Вставить("id", КодТовара); // your identifier
Товар.Вставить("name", НаименованиеТовара);
Товар.Вставить("isGroup", Ложь);
Товар.Вставить("type", "PRODUCT");
Товар.Вставить("uomId", Новый Структура("wmsId", ИдЕдиницыWMS)); // a WMS identifier
Строка1 = Новый Структура;
Строка1.Вставить("lineNumber", 1);
Строка1.Вставить("productId", КодТовара); // your identifier
Строка1.Вставить("quantity", Количество);
Строка1.Вставить("packQuantity", Количество);
Строки = Новый Массив;
Строки.Добавить(Строка1);
Приемка = Новый Структура;
Приемка.Вставить("id", КодПриемки); // your identifier of the document
Приемка.Вставить("status", "TO_RECEIVE");
Приемка.Вставить("date", Формат(Дата, "ДФ=yyyy-MM-dd"));
Приемка.Вставить("warehouseId", Новый Структура("wmsId", ИдСкладаWMS)); // a WMS identifier
Приемка.Вставить("senderContainerHandlingMode", "NOT_USED");
Приемка.Вставить("receivingContainerRequirement", "NONE");
Приемка.Вставить("qcRequired", Ложь);
Приемка.Вставить("allowOverReceiving", Ложь);
Приемка.Вставить("lines", Строки);
Элементы = Новый Массив;
Элементы.Добавить(Новый Структура("entityType, importMode, payload", "PRODUCT", "UPSERT", Товар));
Элементы.Добавить(Новый Структура("entityType, importMode, payload", "RECEIPT", "UPSERT", Приемка));
Результат = ИмпортироватьЭлементы(Подключение, Элементы);
Если Результат.Ошибочные.Количество() > 0 Тогда
ВызватьИсключение "WMS: приемка не загружена";
КонецЕсли;
Итоги = Результат.Ответ["results"];
Возврат Новый Структура("Товар, Приемка", Итоги[0]["internalEntityId"], Итоги[1]["internalEntityId"]);
КонецФункции
3. Receive the receipt back
When the receipt changes in the WMS — the goods are received, the receipt is confirmed — the change feed delivers its current state. Only changes made in the WMS come back: the receipt your system just sent does not return as an echo of its own request. The part of the payload with identifiers:
{
"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.extandexecutions[].productId.exthold your codes: find the document and the product in your system by them.warehouseId.extisnull: the warehouse was never sent by your system. Match it by theintyou used in{"wmsId": …}.receivingZoneIdwas not in your request: the WMS filled it from the warehouse settings. Itsextisnulltoo.createdByIdis a WMS user. Users never have anext.- Quantities are decimal numbers in strings. Convert them to a decimal type.
- The receipt lines come back in
executions, with the planned and the received quantity of each line.
- JavaScript
- Python
- 1C
// 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`
// }
// });
from decimal import Decimal
def read_receipt(payload):
"""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
(None when the record did not come from your system)."""
return {
"wms_id": payload["id"]["int"],
"external_id": payload["id"]["ext"], # the `id` you sent, in lower case
"status": payload["status"],
"warehouse": payload["warehouseId"],
"created_by": payload["createdById"], # a WMS user: `ext` is always None
"lines": [
{
"line_number": line["lineNumber"],
"product": line["productId"],
"planned": Decimal(line["quantityPlan"]),
"received": Decimal(line["quantityExecuted"]),
}
for line in payload["executions"]
],
}
def find_local_record(ref, local_by_code, local_by_wms_id):
"""Finds your record by your identifier, or by a WMS identifier you stored before."""
return (ref["ext"] and local_by_code.get(ref["ext"])) or local_by_wms_id.get(ref["int"])
# Usage with the change feed:
# def on_event(event, payload):
# if event["entityType"] != "RECEIPT":
# return # other types are handled elsewhere
# receipt = read_receipt(payload)
# for line in receipt["lines"]:
# product = find_local_record(line["product"], products_by_code, products_by_wms_id)
# ... # update the received quantity of `product` in your document receipt["external_id"]
#
# poll_change_feed(on_event)
// Every identifier in a payload from the WMS is a pair: "int" is the WMS
// identifier, "ext" is yours (Неопределено when the record did not come from your system).
Функция ВнутреннийИд(Ссылка) Экспорт
Возврат ?(Ссылка = Неопределено, Неопределено, Ссылка["int"]);
КонецФункции
Функция ВнешнийИд(Ссылка) Экспорт
Возврат ?(Ссылка = Неопределено, Неопределено, Ссылка["ext"]);
КонецФункции
// Turns a receipt payload from the change feed into what your system needs.
Функция РазобратьПриемку(Данные) Экспорт
Приемка = Новый Структура;
Приемка.Вставить("ИдWMS", ВнутреннийИд(Данные["id"]));
Приемка.Вставить("ВнешнийИд", ВнешнийИд(Данные["id"])); // the id you sent, in lower case
Приемка.Вставить("Статус", Данные["status"]);
Приемка.Вставить("Склад", Данные["warehouseId"]);
Приемка.Вставить("Автор", Данные["createdById"]); // a WMS user: "ext" is always Неопределено
Строки = Новый Массив;
Для Каждого Исполнение Из Данные["executions"] Цикл
СтрокаПриемки = Новый Структура;
СтрокаПриемки.Вставить("НомерСтроки", Исполнение["lineNumber"]);
СтрокаПриемки.Вставить("Товар", Исполнение["productId"]);
СтрокаПриемки.Вставить("План", Число(Исполнение["quantityPlan"]));
СтрокаПриемки.Вставить("Принято", Число(Исполнение["quantityExecuted"]));
Строки.Добавить(СтрокаПриемки);
КонецЦикла;
Приемка.Вставить("Строки", Строки);
Возврат Приемка;
КонецФункции
// In ОбработатьСобытие of the change feed:
// Если Событие["entityType"] = "RECEIPT" Тогда
// Приемка = РазобратьПриемку(Данные);
// Для Каждого СтрокаПриемки Из Приемка.Строки Цикл
// // Find your product by ВнешнийИд(СтрокаПриемки.Товар); when it is Неопределено,
// // by the WMS identifier ВнутреннийИд(СтрокаПриемки.Товар) you stored before.
// КонецЦикла;
// КонецЕсли;