Создает перемещение материалов или продуктов между складами.

```
v1/transfers/add.php
```

## Параметры

| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| source_storage_id | int | Да | Склад, с которого перемещаются позиции |
| target_storage_id | int | Да | Склад, на который перемещаются позиции |
| materials | array | materials или products | Перемещаемые материалы: id или sku и amount |
| products | array | materials или products | Перемещаемые продукты: id или sku и amount |
| num | string | Нет | Номер. По умолчанию следующий по порядку |
| date | string | Нет | Дата перемещения, YYYY-MM-DD. По умолчанию сегодня |
| notes | string | Нет | Заметки |

Строка materials и products:

| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| id | int | id или sku | ID материала или продукта |
| sku | string | id или sku | Артикул |
| amount | float | Да | Количество, больше 0 |

Передайте строки только в одном массиве: перемещение переносит либо материалы, либо продукты. Тип перемещения определяется по заполненному массиву. Как указывать позицию по id или артикулу, описано в статье [Общие правила](https://developers.controlata.ru/hc/api-docs/articles/rules).

## Как работает

* **Статус** берется из настройки **Статус нового перемещения по умолчанию**. От него зависит, списаны ли позиции с источника и поступили ли на получатель (см. [Перемещения](https://developers.controlata.ru/hc/api-docs/articles/transfers)).
* **Склады** должны различаться и хранить позиции типа перемещения.
* **Себестоимость** считается на складе-источнике по FIFO и переносится на склад-получатель.

## Пример запроса

```
{
    "source_storage_id": 3998,
    "target_storage_id": 4001,
    "date": "2026-10-06",
    "products": [
        {
            "id": 512,
            "amount": 5
        },
        {
            "sku": "P-CHAIR-01",
            "amount": 20
        }
    ],
    "notes": "В магазин на Ленина"
}
```

## Пример ответа

```
{
    "success": true,
    "transfer_id": 6967,
    "num": "31",
    "status": 0
}
```

В ответе приходят ID, номер и код статуса нового перемещения.

## Ошибки

| Ошибка | Причина |
|---|---|
| No source_storage_id in input | Не передано обязательное поле (вместо source_storage_id будет имя поля) |
| A transfer moves either materials or products. Create separate transfers | Переданы и materials, и products |
| No products or materials in input | Не передано ни одной строки |
| Products is not an array | products не массив (так же для materials) |
| Line 0 of products must be an object | Строка не объект (вместо 0 будет номер строки) |
| SKU or id not set for product 0 | В строке нет ни id, ни sku |
| Product with id 512 not found | Продукт не найден или удален (для артикула: Product with SKU "P-CHAIR-01" not found) |
| Amount must be greater than 0 for product with id 512 | Количество не число или не больше 0 после округления |
| Storage ID is not set | Склад равен 0 или пустой |
| Storage ID not found | Склад не найден или удален |
| Source and target storage locations must be different | Передан один и тот же склад |
| Storage location 4001 does not store products | Склад не хранит позиции этого типа (для материалов: does not store materials) |
| Date is not a valid date in format YYYY-MM-DD | Неверный формат даты |
