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

```
v1/purchases/add.php
```

## Параметры

| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| supplier_id | int | Один из двух | ID существующего поставщика |
| supplier_name | string | Один из двух | Имя нового поставщика. Остальные поля поставщика передаются с префиксом supplier_ |
| materials | array | Один из двух | Строки материалов |
| products | array | Один из двух | Строки продуктов |
| date_placed | string | Нет | Дата заказа поставки. По умолчанию сегодня |
| date_received | string | Нет | Дата получения |
| materials_storage_id | int | Нет | Склад материалов. По умолчанию склад из настроек |
| products_storage_id | int | Нет | Склад продуктов. По умолчанию склад из настроек |
| delivery_price | float | Нет | Стоимость доставки. По умолчанию 0 |
| discount | float | Нет | Скидка. По умолчанию 0 |
| notes | string | Нет | Заметки |

Каждая строка в materials и products содержит id или sku, количество amount и сумму строки total. Поля поставщика и строк описаны в статье [Поставки](https://developers.controlata.ru/hc/api-docs/articles/purchases).

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

* **Себестоимость строк.** Доставка и скидка распределяются по строкам пропорционально их суммам.
* **Цены.** Цена каждого материала становится равной себестоимости единицы из поставки, независимо от статуса. Продукт без состава получает себестоимость единицы из поставки. Себестоимость продуктов, в состав которых входят материалы поставки, пересчитывается.
* **Поставщик.** С supplier_name каждый запрос создает нового поставщика, даже если такое имя уже есть. Поставщик создается только после проверки строк. Поставщик поставки добавляется в поставщики ее материалов и продуктов.
* **Даты.** Движения по складу датируются датой получения, а если она не задана, датой заказа.
* **Неизвестные позиции.** Если хотя бы одна позиция не найдена, поставка не создается.

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

```
{
    "supplier_id": 45,
    "date_placed": "2026-10-06",
    "materials_storage_id": 3998,
    "materials": [
        {
            "sku": "M010",
            "amount": 0.2,
            "total": 26000
        },
        {
            "id": 2052,
            "amount": 10,
            "total": 4000
        }
    ],
    "delivery_price": 1500,
    "notes": "Счет № 118"
}
```

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

```
{
    "success": true,
    "purchase_id": 29645,
    "status": "1"
}
```

status содержит код статуса, в котором создана поставка.

## Ошибки

| Ошибка | Причина |
|---|---|
| No supplier_name or supplier_id in input | Не передан поставщик |
| Supplier not found or access denied | Поставщик supplier_id не найден или удален |
| Supplier name must not be empty | Пустое supplier_name |
| Supplier name must be a string | supplier_name не строка |
| Invalid supplier_type value. Must be one of: 1, 2, 3 | Неверный тип нового поставщика |
| Storage ID not found | Склад не найден или удален |
| Materials is not an array | materials не массив (так же для products) |
| No products or materials in input | Не передано ни одной строки |
| Line 0 of materials must be an object | Строка не является объектом (вместо 0 будет номер строки) |
| SKU or id not set for material 0 | В строке нет ни id, ни sku |
| Material with SKU "M010" not found | Позиция не найдена или удалена |
| Amount must be greater than 0 for material with SKU "M010" | Количество не передано, не число или не больше 0 после округления |
| Total must be 0 or greater for material with SKU "M010" | Сумма строки не передана, не число или меньше 0 |
| Date is not a valid date in format YYYY-MM-DD | Неверная дата заказа или получения |

В текстах ошибок строк вместо material будет product для строк продуктов, а вместо SKU "M010" будет id 2052, если строка передана по id.
