Поставки

8 статьи Максим От Максим

Методы для поставок, их статусов и оплаты

Поставки

Поставки: закупки материалов и продуктов у поставщиков. Поставка пополняет остатки на складе и обновляет цены материалов. Через API поставки можно создавать, редактировать и удалять, менять статус и статус оплаты, получать список поставок и данные поставки. Пути методов указаны относительно базового адреса API, а общие для всех методов правила (авторизация, формат запросов, частичное редактирование, строки операций, постраничная выдача) описаны в статьях Обзор API и Общие правила. Методы | Метод | Что делает | |---|---| | v1/purchases/add | Создает поставку | | v1/purchases/edit | Изменяет поставку | | v1/purchases/delete | Удаляет поставку | | v1/purchases/update_status | Меняет статус поставки | | v1/purchases/update_payment | Меняет статус оплаты | | v1/purchases/get_list | Возвращает поставки компании | | v1/purchases/get_entry | Возвращает данные поставки со строками | Поля поставки | Поле | Тип | Описание | |---|---|---| | id | int | ID поставки | | status | int | Статус, код из таблицы ниже | | payment | int | Статус оплаты, код из таблицы ниже | | date_placed | string | Дата заказа поставки | | date_received | string | Дата получения. Пустая строка, если не задана | | supplier_id | int | ID поставщика | | supplier_name | string | Наименование поставщика | | materials_storage_id | int | Склад материалов | | materials_storage_name | string | Название склада материалов | | products_storage_id | int | Склад продуктов | | products_storage_name | string | Название склада продуктов | | subtotal | float | Сумма строк | | delivery_price | float | Стоимость доставки | | discount | float | Скидка | | total | float | Итого: subtotal плюс delivery_price минус discount | | amount | float | Общее количество, если у всех строк одна единица измерения, иначе null | | lines | int | Число строк | | shipments_count | int | Число отгрузок, которыми получена поставка | | notes | string | Заметки | Статусы | Код | Статус | Влияние на остатки | |---|---|---| | 0 | План | Остаток не меняется, количество попадает в запланированное изменение (planned) | | 1 | Заказана | Как в статусе «План»: остаток не меняется, количество в запланированном изменении | | 2 | Частично получена | Полученная часть поступила на склад, остальное в запланированном изменении | | 3 | Получена | Материалы и продукты поступают на склад | Новая поставка получает статус из настройки Статус новой поставки по умолчанию в разделе Настройки → Основные. Дальше статус меняется методом v1/purchases/update_status. Статус «Частично получена» через API не ставится: он появляется, когда часть поставки получают отгрузками в интерфейсе Controlata. Подробнее о запланированном изменении остатка в статье Материалы. Статусы оплаты | Код | Статус | |---|---| | 0 | Не оплачена | | 1 | Частично оплачена | | 2 | Оплачена | Новая поставка создается неоплаченной. Статус оплаты меняет v1/purchases/update_payment. Это только отметка: на остатки и суммы она не влияет. Строки поставки Состав поставки передается в двух массивах: materials для материалов и products для продуктов. Нужна хотя бы одна строка. | Поле | Тип | Обязательное | Описание | |---|---|---|---| | id | int | id или sku | ID материала или продукта | | sku | string | id или sku | Артикул. Продукт ищется и по альтернативным артикулам | | amount | float | Да | Количество, больше 0 | | total | float | Да | Сумма строки до доставки и скидки, 0 или больше | В отличие от заказов, неизвестная позиция не пропускается: запрос отклоняется с ошибкой, и поставка не создается. Подробнее о поиске позиций в статье Общие правила. Доставка, скидка и себестоимость строк Доставка и скидка распределяются по строкам пропорционально их суммам. Себестоимость строки (cost) равна ее сумме (total), умноженной на отношение total поставки к subtotal. Например, в поставке две строки: доска на 26000 и клей на 4000, доставка 1500. Сумма строк 30000, доставка добавляет к каждой строке 5%: | Строка | total | cost | |---|---|---| | Доска дубовая, 0.2 куб. м | 26000 | 27300 | | Клей столярный, 10 кг | 4000 | 4200 | v1/purchases/get_entry возвращает в строке оба значения: total как его передали и cost после распределения. Цены материалов и себестоимость продуктов - Цена материала становится равной себестоимости единицы из поставки: cost строки, деленный на количество. В примере выше доска получит цену 136500 за куб. м. Цена обновляется сразу при создании, в любом статусе. После этого Controlata пересчитывает себестоимость продуктов, в состав которых входит материал. - Продукт без состава (без материалов, продуктов и ресурсов в составе) получает себестоимость единицы из поставки. У продукта с составом себестоимость по-прежнему считается по составу. - Поставщик добавляется в поставщики материалов и продуктов поставки. - При редактировании цены обновляются только по измененным строкам. Удаление поставки цены не откатывает. Склады Материалы поступают на склад materials_storage_id, продукты на склад products_storage_id. Если склад не передан, берется склад из настроек Склад по умолчанию для поставок материалов и Склад по умолчанию для поставок продуктов (на странице Склады, кнопка Склады по умолчанию). ID складов возвращает v1/storages/get_list. Поставщик Поставщик указывается одним из двух способов: - supplier_id: ID существующего поставщика, например из v1/suppliers/add; - supplier_name: имя нового поставщика. Controlata создаст его вместе с поставкой из полей ниже. | Поле | Тип | Описание | |---|---|---| | supplier_name | string | Наименование юрлица или имя ИП и физлица | | supplier_type | int | Тип: 1 юрлицо, 2 ИП, 3 физлицо. По умолчанию 1 | | supplier_email | string | Электронная почта | | supplier_phone | string | Телефон | | supplier_address | string | Юридический адрес | | supplier_inn | string | ИНН | | supplier_kpp | string | КПП | | supplier_ogrn | string | ОГРН | | supplier_agreement | string | Договор | | supplier_manager_name | string | Руководитель | | supplier_manager_post | string | Должность руководителя | | supplier_notes | string | Заметки о поставщике | Если переданы оба поля, используется supplier_id, а поля supplier_* игнорируются. Каждая новая поставка с supplier_name создает нового поставщика, даже если поставщик с таким именем уже есть. Для постоянных поставщиков сохраните ID на своей стороне и передавайте supplier_id. Подробнее о полях в статье Поставщики.

Создание поставки

Создает поставку. Статус поставки берется из настройки Статус новой поставки по умолчанию, а от статуса зависит, поступят ли материалы и продукты на склад сразу (см. Поставки). 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. Поля поставщика и строк описаны в статье Поставки. Как работает - Себестоимость строк. Доставка и скидка распределяются по строкам пропорционально их суммам. - Цены. Цена каждого материала становится равной себестоимости единицы из поставки, независимо от статуса. Продукт без состава получает себестоимость единицы из поставки. Себестоимость продуктов, в состав которых входят материалы поставки, пересчитывается. - Поставщик. С 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.

Редактирование поставки

Изменяет поставку. Меняются только переданные поля, остальные остаются прежними. Подробнее о частичном редактировании в статье Общие правила. v1/purchases/edit.php Параметры | Поле | Тип | Обязательное | Описание | |---|---|---|---| | purchase_id | int | Да | ID поставки | | 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 | Нет | Стоимость доставки | | discount | float | Нет | Скидка | | notes | string | Нет | Заметки | Статус и статус оплаты этим методом не меняются, для них есть v1/purchases/update_status и v1/purchases/update_payment. Как работает - Строки. Если передан materials или products, состав заменяется целиком, а непереданный массив считается пустым. Строки из ответа v1/purchases/get_entry можно отправить обратно без изменений. - Строки не переданы. Controlata восстанавливает суммы строк такими, какими их ввели, до распределения доставки и скидки. Поэтому, если изменить только delivery_price или discount, суммы строк останутся прежними, а себестоимость строк распределится заново. - Скидка на всю сумму. Если итог поставки равен 0 (скидка равна сумме строк и доставке), исходные суммы строк восстановить нельзя. Тогда передайте materials и products явно, иначе запрос будет отклонен. - Цены. Цены материалов и себестоимость продуктов без состава обновляются только по строкам, у которых изменились количество, сумма или себестоимость. Изменение доставки или скидки меняет себестоимость всех строк, поэтому обновит цены всех позиций поставки. - Поставщик. Без supplier_id и supplier_name поставщик остается прежним. supplier_name с тем же именем, что у текущего поставщика, не создает дубль. Другое имя создает нового поставщика. Текущего поставщика можно передать по supplier_id, даже если он уже удален. - Склады. При смене склада поступление переносится на новый склад, остатки пересчитываются на обоих складах. - Статус сохраняется. Если поставка уже получена, новые строки сразу поступают на склад. Если поставка получалась частями, изменение количества сначала затрагивает неполученную часть. Пример запроса Изменить стоимость доставки, не передавая строки: { "purchase_id": 29645, "delivery_price": 3000 } Суммы строк останутся 26000 и 4000, а себестоимость станет 28600 и 4400. Цены материалов обновятся по новой себестоимости. Заменить состав поставки: { "purchase_id": 29645, "materials": [ { "sku": "M010", "amount": 0.25, "total": 32500 } ] } Пример ответа { "success": true } Ошибки | Ошибка | Причина | |---|---| | No purchase_id in input | Не передан purchase_id | | Purchase not found or access denied | Поставка не найдена или удалена | | The purchase total is 0, so line totals cannot be restored. Pass materials and products explicitly | Итог поставки равен 0, а строки не переданы | | Storage ID is not set | Передан пустой склад | | Storage ID not found | Склад не найден или удален | | Date is not a valid date in format YYYY-MM-DD | Неверная дата. Пустая date_placed тоже отклоняется | | Materials is not an array | materials не массив (так же для products) | | No products or materials in input | Переданы пустые materials и products | | Material with SKU "M010" not found | Позиция не найдена или удалена | | Supplier not found or access denied | Поставщик supplier_id не найден или удален | | Supplier name must not be empty | Пустое supplier_name | | Invalid supplier_type value. Must be one of: 1, 2, 3 | Неверный тип нового поставщика | Остальные ошибки в строках те же, что в v1/purchases/add.

Удаление поставки

Удаляет поставку. v1/purchases/delete.php Параметры | Поле | Тип | Обязательное | Описание | |---|---|---|---| | purchase_id | int | Да | ID поставки | Как работает - Поступления материалов и продуктов по поставке удаляются, остатки на складах пересчитываются. - Цены материалов и себестоимость продуктов, обновленные поставкой, не возвращаются к прежним значениям. - Файлы поставки удаляются. - Поставщик остается в Controlata. Удаление нельзя отменить. Пример запроса { "purchase_id": 29645 } Пример ответа { "success": true } Ошибки | Ошибка | Причина | |---|---| | No purchase_id in input | Не передан purchase_id | | Purchase not found or access denied | Поставка не найдена или уже удалена |

Смена статуса поставки

Меняет статус поставки. От статуса зависит, поступили ли материалы и продукты поставки на склад (см. Поставки). v1/purchases/update_status.php Параметры | Поле | Тип | Обязательное | Описание | |---|---|---|---| | purchase_id | int | Да | ID поставки | | status | int | Да | Новый статус: 0 План, 1 Заказана, 3 Получена | | date_received | string | Нет | Дата получения. Учитывается при переходе в статус «Получена» | Статус 2 «Частично получена» через API не ставится: он появляется, когда часть поставки получают отгрузками в интерфейсе Controlata. Как работает - Остатки. В статусе «Получена» материалы и продукты поступают на склад. В статусах «План» и «Заказана» количество попадает в запланированное изменение остатка. Остатки пересчитываются сразу. - Цены. Смена статуса цены материалов не меняет: они обновляются уже при создании и редактировании поставки. - Дата получения. При переходе в «Получена» переданная date_received записывается в поставку, и поступление датируется ею. Без date_received дата получения не меняется. В других статусах date_received игнорируется. - Частичное получение. Если поставка была в статусе «Частично получена», при переходе в «Получена» неполученная часть оформляется еще одной отгрузкой. - Возврат из полученных. При переходе из «Получена» или «Частично получена» в «План» или «Заказана» отгрузки поставки удаляются, и все количество снова становится запланированным. - Тот же статус. Если поставка уже в переданном статусе, ничего не меняется, и метод отвечает успехом. Пример запроса { "purchase_id": 29645, "status": 3, "date_received": "2026-10-09" } Пример ответа { "success": true } Ошибки | Ошибка | Причина | |---|---| | No purchase_id in input | Не передано обязательное поле (вместо purchase_id будет имя поля) | | Invalid status value. Must be one of: 0, 1, 3 | Неверный статус, в том числе 2 | | Purchase not found or access denied | Поставка не найдена или удалена | | Date is not a valid date in format YYYY-MM-DD | Неверная date_received |

Смена статуса оплаты поставки

Меняет статус оплаты поставки. Статус оплаты только отмечает, оплачена ли поставка поставщику: на остатки, суммы и статус поставки он не влияет. v1/purchases/update_payment.php Параметры | Поле | Тип | Обязательное | Описание | |---|---|---|---| | purchase_id | int | Да | ID поставки | | status | int | Да | Статус оплаты: 0 Не оплачена, 1 Частично оплачена, 2 Оплачена | Статус оплаты виден в списке поставок, если в разделе Настройки → Основные включено Показывать статус оплаты поставок. Через API он меняется и возвращается независимо от этой настройки. Пример запроса { "purchase_id": 29645, "status": 2 } Пример ответа { "success": true } Ошибки | Ошибка | Причина | |---|---| | No purchase_id in input | Не передано обязательное поле (вместо purchase_id будет имя поля) | | Invalid payment status value. Must be one of: 0, 1, 2 | Неверный статус оплаты | | Purchase not found or access denied | Поставка не найдена или удалена |

Список поставок

Возвращает поставки компании, от новых к старым по дате заказа поставки. Строки поставок в список не входят, их возвращает v1/purchases/get_entry. v1/purchases/get_list.php Параметры | Поле | Тип | Обязательное | Описание | |---|---|---|---| | date_from | string | Нет | Поставки с этой даты заказа включительно | | date_to | string | Нет | Поставки по эту дату заказа включительно | | supplier_id | int | Нет | Только поставки этого поставщика | | limit | int | Нет | Размер страницы, от 1 до 1000 | | offset | int | Нет | Сколько записей пропустить | Фильтры по датам работают по date_placed. Без параметров возвращаются все поставки компании. Подробнее о постраничной выдаче в статье Общие правила. Ответ Массив purchases с полями поставки (см. Поставки). Поле total в корне ответа содержит общее число поставок, подходящих под фильтры. Пример запроса { "date_from": "2026-10-01", "supplier_id": 45, "limit": 100, "offset": 0 } Пример ответа { "success": true, "purchases": [ { "id": "29645", "status": "1", "payment": "0", "date_placed": "2026-10-06", "date_received": "", "supplier_id": "45", "supplier_name": "ООО Лесторг", "materials_storage_id": "3998", "materials_storage_name": "Основной склад", "products_storage_id": "3998", "products_storage_name": "Основной склад", "subtotal": "30000.00", "delivery_price": "1500.00", "discount": "0.00", "total": "31500.00", "amount": null, "lines": "2", "shipments_count": "0", "notes": "Счет № 118" } ], "total": 1 } Ошибки | Ошибка | Причина | |---|---| | Date is not a valid date in format YYYY-MM-DD | Неверная date_from или date_to | | Invalid limit value. Must be between 1 and 1000 | Неверный limit | | Invalid offset value. Must be 0 or greater | Неверный offset | | Offset requires limit | Передан offset без limit |

Данные поставки

Возвращает данные поставки и ее строки. v1/purchases/get_entry.php Параметры | Поле | Тип | Обязательное | Описание | |---|---|---|---| | purchase_id | int | Да | ID поставки | Ответ Объект purchase с полями поставки (см. Поставки) и двумя массивами строк: materials и products. Поля строки: | Поле | Тип | Описание | |---|---|---| | id | int | ID материала или продукта | | sku | string | Артикул | | name | string | Название | | amount | float | Количество | | unit | string | Единица измерения | | total | float | Сумма строки, как ее ввели: до доставки и скидки | | price | float | Цена за единицу: total, деленный на amount | | cost | float | Себестоимость строки с учетом доставки и скидки | | position | int | Номер строки в карточке поставки, от 0 | Нумерация position сквозная для обоих массивов: по ней можно восстановить порядок строк, как в карточке поставки. Если строка получалась частями, ее количество и суммы приходят общими. Поля total, price и cost строки приходят числами, а не строками, и округляются до копеек. Если итог поставки равен 0 (скидка на всю сумму), total и price строк равны 0. Строки из ответа можно отправить в v1/purchases/edit без изменений: лишние поля игнорируются. Пример запроса { "purchase_id": 29645 } Пример ответа { "success": true, "purchase": { "id": "29645", "status": "1", "payment": "0", "date_placed": "2026-10-06", "date_received": "", "supplier_id": "45", "supplier_name": "ООО Лесторг", "materials_storage_id": "3998", "materials_storage_name": "Основной склад", "products_storage_id": "3998", "products_storage_name": "Основной склад", "subtotal": "30000.00", "delivery_price": "1500.00", "discount": "0.00", "total": "31500.00", "amount": null, "lines": "2", "shipments_count": "0", "notes": "Счет № 118", "materials": [ { "id": "2051", "sku": "M010", "name": "Доска дубовая", "amount": "0.200", "cost": 27300, "unit": "куб. м", "position": "0", "total": 26000, "price": 130000 }, { "id": "2052", "sku": "M011", "name": "Клей столярный", "amount": "10.000", "cost": 4200, "unit": "кг", "position": "1", "total": 4000, "price": 400 } ], "products": [] } } Ошибки | Ошибка | Причина | |---|---| | No purchase_id in input | Не передан purchase_id | | Purchase not found or access denied | Поставка не найдена или удалена |