Инвентаризация
Пересчёт товаров склада — полный (весь склад) или частичный (выбранные категории и товары). Пока подсчёт идёт, склад недоступен для продаж и перемещений; подтверждение создаёт Приход на излишки и Списание на недостачи.
| Метод | Адрес | Назначение |
|---|---|---|
| GET | /company/trade/inventory/stats | Статистика инвентаризаций |
| GET | /company/trade/inventory/categories | Категории для подсчёта |
| PATCH | /company/trade/inventory/{model}/add-products | Добавить товары в подсчёт |
| PATCH | /company/trade/inventory/{model}/remove-products | Убрать товары из подсчёта |
| GET | /company/trade/inventory/{model}/comparison-sheet | Сличительная ведомость |
| PATCH | /company/trade/inventory/{model}/complete | Подтвердить и обновить остаток |
| PATCH | /company/trade/inventory/{model}/cancel | Отменить инвентаризацию |
| GET | /company/trade/inventory | История инвентаризаций |
| GET | /company/trade/inventory/{model} | Детали инвентаризации |
| POST | /company/trade/inventory | Начать инвентаризацию |
Статистика инвентаризаций
/company/trade/inventory/statsКарточки над историей: всего подсчётов total_count, дата последнего завершённого last_completed_at, точность accuracy_percent (совпавшие позиции к проверенным по всем завершённым подсчётам, null без данных) и разница последнего подсчёта в деньгах по валютам last_difference_amounts.
Заголовки
| Заголовок | Значение | Описание |
|---|---|---|
Authorization | Bearer {token} | Токен из POST /common/auth/login |
Accept | application/json | Ответ в JSON |
Accept-Language | ru | Язык сообщений и названий: ru, uz, oz |
Ответ · 200
Поля ответа
| Поле | Тип | Описание |
|---|---|---|
total_count | integer | |
last_completed_at | string | |
accuracy_percent | null | |
last_difference_amounts | object | |
last_difference_amounts.uzs | integer | |
last_difference_amounts.usd | integer | |
last_difference_amounts.eur | integer | |
last_difference_amounts.rub | integer |
{
"total_count": 2,
"last_completed_at": "2026-09-30 12:47:59",
"accuracy_percent": null,
"last_difference_amounts": {
"uzs": 2000,
"usd": 2000,
"eur": 2000,
"rub": 2000
}
}Категории для подсчёта
/company/trade/inventory/categoriesКаталог категорий склада stock_id для частичной инвентаризации: что лежит в каждой категории и на какую сумму по приходной цене. Склад должен принадлежать компании пользователя или её филиалу.
Заголовки
| Заголовок | Значение | Описание |
|---|---|---|
Authorization | Bearer {token} | Токен из POST /common/auth/login |
Accept | application/json | Ответ в JSON |
Accept-Language | ru | Язык сообщений и названий: ru, uz, oz |
Параметры запроса
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
stock_id | integer | Да | Склад. ID существующей записи, доступной пользователю |
Ответ · 200
Поля ответа
| Поле | Тип | Описание |
|---|---|---|
data | object[] | Данные |
data[].id | integer | ID |
data[].name | object | Название |
data[].name.oz | string | |
data[].name.ru | string | |
data[].name.uz | string | |
data[].text | string | Текст |
data[].parent_id | integer | Родитель |
data[].products_count | integer | |
data[].quantity | integer | Количество |
data[].amounts | object | |
data[].amounts.uzs | integer | |
data[].amounts.usd | integer | |
data[].amounts.eur | integer | |
data[].amounts.rub | integer | |
total | object | Всего записей |
total.products_count | integer | |
total.quantity | integer | Количество |
total.amounts | object | |
total.amounts.uzs | integer | |
total.amounts.usd | integer | |
total.amounts.eur | integer | |
total.amounts.rub | integer |
{
"data": [
{
"id": 4,
"name": {
"oz": "Category 1-1-1 oz",
"ru": "Category 1-1-1 ru",
"uz": "Category 1-1-1 uz"
},
"text": "Category 1-1-1 ru",
"parent_id": 3,
"products_count": 2,
"quantity": 3,
"amounts": {
"uzs": 1000,
"usd": 4260,
"eur": 0,
"rub": 0
}
}
],
"total": {
"products_count": 2,
"quantity": 3,
"amounts": {
"uzs": 1000,
"usd": 4260,
"eur": 0,
"rub": 0
}
}
}Пример ошибки · 422
{
"message": "Поле Склад обязательно для заполнения.",
"errors": {
"stock_id": [
"Поле Склад обязательно для заполнения."
]
}
}Добавить товары в подсчёт
/company/trade/inventory/{model}/add-productsДобавляет в идущую инвентаризацию позиции склада (stock_product_id — ID строки остатка этого склада) с фактическим количеством. Нельзя добавить товар, которого нет ни по учёту, ни по факту; не больше 10 000 позиций на подсчёт. Только для статуса in_progress.
Из формы (
multipart/form-data) методPATCHотправляется какPOSTс параметром?_method=PATCH.
Заголовки
| Заголовок | Значение | Описание |
|---|---|---|
Authorization | Bearer {token} | Токен из POST /common/auth/login |
Accept | application/json | Ответ в JSON |
Accept-Language | ru | Язык сообщений и названий: ru, uz, oz |
Параметры пути
| Параметр | Описание |
|---|---|
model | ID записи |
Тело запроса
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
products_tmp | object[] | Да | Продукты. Макс. 100 элементов |
products_tmp[].stock_product_id | integer | Да | Продукт на складе. Без повторов |
products_tmp[].actual_quantity | number | Да | Фактическое количество. До 4 знаков после запятой. Не меньше 0 |
{
"products_tmp": [
{
"stock_product_id": 1,
"actual_quantity": 10
},
{
"stock_product_id": 2,
"actual_quantity": 0.2
}
]
}curl -X PATCH "https://api.wasyt.uz/company/trade/inventory/1/add-products" \
-H "Accept: application/json" \
-H "Accept-Language: ru" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{"products_tmp":[{"stock_product_id":1,"actual_quantity":10},{"stock_product_id":2,"actual_quantity":0.2}]}'Ответ · 200
Поля ответа
| Поле | Тип | Описание |
|---|---|---|
message | string | Сообщение |
{
"message": "Success"
}Убрать товары из подсчёта
/company/trade/inventory/{model}/remove-productsУдаляет из идущей инвентаризации строки с переданными ID строк инвентаризации и пересчитывает её итоги. Только для статуса in_progress.
Из формы (
multipart/form-data) методPATCHотправляется какPOSTс параметром?_method=PATCH.
Заголовки
| Заголовок | Значение | Описание |
|---|---|---|
Authorization | Bearer {token} | Токен из POST /common/auth/login |
Accept | application/json | Ответ в JSON |
Accept-Language | ru | Язык сообщений и названий: ru, uz, oz |
Параметры пути
| Параметр | Описание |
|---|---|
model | ID записи |
Тело запроса
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
products_tmp | array | Да | Продукты. Макс. 100 элементов |
products_tmp[] | integer | Да | Продукты. Без повторов |
{
"products_tmp": [
1
]
}curl -X PATCH "https://api.wasyt.uz/company/trade/inventory/1/remove-products" \
-H "Accept: application/json" \
-H "Accept-Language: ru" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{"products_tmp":[1]}'Ответ · 200
Поля ответа
| Поле | Тип | Описание |
|---|---|---|
message | string | Сообщение |
{
"message": "Success"
}Сличительная ведомость
/company/trade/inventory/{model}/comparison-sheetСкачивает Excel-файл сличительной ведомости по проверенным строкам подсчёта. Доступно и до, и после подтверждения инвентаризации.
Заголовки
| Заголовок | Значение | Описание |
|---|---|---|
Authorization | Bearer {token} | Токен из POST /common/auth/login |
Accept | application/json | Ответ в JSON |
Accept-Language | ru | Язык сообщений и названий: ru, uz, oz |
Параметры пути
| Параметр | Описание |
|---|---|
model | ID записи |
Ответ · 200
Ответ — файл или текст, не JSON.
Подтвердить и обновить остаток
/company/trade/inventory/{model}/completeЗавершает подсчёт одной транзакцией: фиксирует количество по учёту на текущий момент, создаёт завершённый Приход без поставщика на излишки (по одному на валюту) и Списание на недостачи с пометкой «Инвентаризация». Учитываются только проверенные строки; ошибка 400, если не проверено ни одной или статус не in_progress.
Из формы (
multipart/form-data) методPATCHотправляется какPOSTс параметром?_method=PATCH.
Заголовки
| Заголовок | Значение | Описание |
|---|---|---|
Authorization | Bearer {token} | Токен из POST /common/auth/login |
Accept | application/json | Ответ в JSON |
Accept-Language | ru | Язык сообщений и названий: ru, uz, oz |
Параметры пути
| Параметр | Описание |
|---|---|
model | ID записи |
Ответ · 200
Поля ответа
| Поле | Тип | Описание |
|---|---|---|
message | string | Сообщение |
{
"message": "Success"
}Отменить инвентаризацию
/company/trade/inventory/{model}/cancelПереводит подсчёт в canceled и удаляет его строки; остатки не меняются, склад снова становится доступен. Только для статуса in_progress.
Из формы (
multipart/form-data) методPATCHотправляется какPOSTс параметром?_method=PATCH.
Заголовки
| Заголовок | Значение | Описание |
|---|---|---|
Authorization | Bearer {token} | Токен из POST /common/auth/login |
Accept | application/json | Ответ в JSON |
Accept-Language | ru | Язык сообщений и названий: ru, uz, oz |
Параметры пути
| Параметр | Описание |
|---|---|
model | ID записи |
Ответ · 200
Поля ответа
| Поле | Тип | Описание |
|---|---|---|
message | string | Сообщение |
{
"message": "Success"
}История инвентаризаций
/company/trade/inventoryИнвентаризации компании и её филиалов с пагинацией и фильтрами; с format=excel — выгрузка списка в Excel.
Заголовки
| Заголовок | Значение | Описание |
|---|---|---|
Authorization | Bearer {token} | Токен из POST /common/auth/login |
Accept | application/json | Ответ в JSON |
Accept-Language | ru | Язык сообщений и названий: ru, uz, oz |
Параметры запроса
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
format | string | Нет | Формат ответа: excel — скачать список файлом Excel вместо JSON (учитывает те же фильтры) |
filter[id] | — | Нет | ID — точное значение |
filter[creator_id] | — | Нет | Создатель — точное значение |
filter[updater_id] | — | Нет | Обновитель — точное значение |
filter[company_id] | — | Нет | Компания — одно значение или список filter[company_id][] |
filter[stock_id] | — | Нет | Склад — точное значение |
filter[responsible_id] | — | Нет | Ответственный — точное значение |
filter[type] | — | Нет | Тип — точное значение |
filter[status] | — | Нет | Статус — точное значение |
filter[created_at] | — | Нет | Создано — период: [0] — с, [1] — по (Y-m-d) |
filter[products.product.category_id] | — | Нет | Категория — точное значение (с учётом вложенных) |
filter[products.product.brand_id] | — | Нет | Бренд — точное значение |
sort[] | — | Нет | Сортировка, - — по убыванию: id, -id |
with[] | — | Нет | Подгрузить связи: creator.profile, updater.profile, responsible.profile, company, stock |
page | — | Нет | Номер страницы, с 1 |
page-size | — | Нет | Записей на странице, не больше 10 |
Ответ · 200
Постраничный ответ: записи в data[], пагинация в links и meta.
Поля ответа
| Поле | Тип | Описание |
|---|---|---|
data | object[] | Данные |
data[].id | integer | ID |
data[].creator_id | integer | Создатель |
data[].updater_id | integer | Обновитель |
data[].company_id | integer | Компания |
data[].stock_id | integer | Склад |
data[].responsible_id | null | Ответственный |
data[].type | string | Тип |
data[].status | string | Статус |
data[].comment | string | Комментарий |
data[].stock_quantity | integer | Кол-во на складе |
data[].actual_quantity | integer | Фактическое количество |
data[].quantity_diff_above | integer | Избыток (кол-во) |
data[].quantity_diff_below | integer | Недосдача (кол-во) |
data[].amounts_diff_above | object | Избыток (сумма) |
data[].amounts_diff_above.eur | integer | |
data[].amounts_diff_above.rub | integer | |
data[].amounts_diff_above.usd | integer | |
data[].amounts_diff_above.uzs | integer | |
data[].amounts_diff_below | object | Недосдача (сумма) |
data[].amounts_diff_below.eur | integer | |
data[].amounts_diff_below.rub | integer | |
data[].amounts_diff_below.usd | integer | |
data[].amounts_diff_below.uzs | integer | |
data[].products_count | integer | |
data[].checked_products_count | integer | |
data[].matched_products_count | integer | |
data[].completed_at | null | |
data[].created_at | string | Создано |
data[].updated_at | string | Обновлено |
{
"data": [
{
"id": 1,
"creator_id": 2,
"updater_id": 2,
"company_id": 1,
"stock_id": 1,
"responsible_id": null,
"type": "partial",
"status": "in_progress",
"comment": "Comment 1",
"stock_quantity": 1,
"actual_quantity": 2,
"quantity_diff_above": 1,
"quantity_diff_below": 0,
"amounts_diff_above": {
"eur": 1000,
"rub": 1000,
"usd": 1000,
"uzs": 1000
},
"amounts_diff_below": {
"eur": 0,
"rub": 0,
"usd": 0,
"uzs": 0
},
"products_count": 0,
"checked_products_count": 0,
"matched_products_count": 0,
"completed_at": null,
"created_at": "2026-09-30 12:47:59",
"updated_at": "2026-09-30 12:47:59"
},
{
"id": 2,
"creator_id": 2,
"updater_id": 2,
"company_id": 1,
"stock_id": 1,
"responsible_id": null,
"type": "partial",
"status": "completed",
"comment": "Comment 2",
"stock_quantity": 3,
"actual_quantity": 5,
"quantity_diff_above": 2,
"quantity_diff_below": 0,
"amounts_diff_above": {
"eur": 2000,
"rub": 2000,
"usd": 2000,
"uzs": 2000
},
"amounts_diff_below": {
"eur": 0,
"rub": 0,
"usd": 0,
"uzs": 0
},
"products_count": 0,
"checked_products_count": 0,
"matched_products_count": 0,
"completed_at": "2026-09-30 12:47:59",
"created_at": "2026-09-30 12:47:59",
"updated_at": "2026-09-30 12:47:59"
}
],
"links": {
"first": "https://api.wasyt.uz/company/trade/inventory?page=1",
"last": "https://api.wasyt.uz/company/trade/inventory?page=1",
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 1,
"links": [],
"path": "https://api.wasyt.uz/company/trade/inventory",
"per_page": 10,
"to": 2,
"total": 2
}
}Детали инвентаризации
/company/trade/inventory/{model}Одна инвентаризация: склад, ответственный, тип, статус, счётчики проверенных позиций и суммы излишков и недостач по валютам.
Заголовки
| Заголовок | Значение | Описание |
|---|---|---|
Authorization | Bearer {token} | Токен из POST /common/auth/login |
Accept | application/json | Ответ в JSON |
Accept-Language | ru | Язык сообщений и названий: ru, uz, oz |
Параметры пути
| Параметр | Описание |
|---|---|
model | ID записи |
Параметры запроса
| Параметр | Описание |
|---|---|
stock_id | Склад |
GET /company/trade/inventory/categories?stock_id=1Ответ · 200
Поля ответа
| Поле | Тип | Описание |
|---|---|---|
data | object[] | Данные |
data[].id | integer | ID |
data[].name | object | Название |
data[].name.oz | string | |
data[].name.ru | string | |
data[].name.uz | string | |
data[].text | string | Текст |
data[].parent_id | integer | Родитель |
data[].products_count | integer | |
data[].quantity | integer | Количество |
data[].amounts | object | |
data[].amounts.uzs | integer | |
data[].amounts.usd | integer | |
data[].amounts.eur | integer | |
data[].amounts.rub | integer | |
total | object | Всего записей |
total.products_count | integer | |
total.quantity | integer | Количество |
total.amounts | object | |
total.amounts.uzs | integer | |
total.amounts.usd | integer | |
total.amounts.eur | integer | |
total.amounts.rub | integer |
{
"data": [
{
"id": 4,
"name": {
"oz": "Category 1-1-1 oz",
"ru": "Category 1-1-1 ru",
"uz": "Category 1-1-1 uz"
},
"text": "Category 1-1-1 ru",
"parent_id": 3,
"products_count": 2,
"quantity": 3,
"amounts": {
"uzs": 1000,
"usd": 4260,
"eur": 0,
"rub": 0
}
}
],
"total": {
"products_count": 2,
"quantity": 3,
"amounts": {
"uzs": 1000,
"usd": 4260,
"eur": 0,
"rub": 0
}
}
}Пример ошибки · 422
{
"message": "Поле Склад обязательно для заполнения.",
"errors": {
"stock_id": [
"Поле Склад обязательно для заполнения."
]
}
}Начать инвентаризацию
/company/trade/inventoryОткрывает подсчёт склада. type = full сразу заполняет лист всем складом, partial — выбранными category_ids и product_ids (без выбора лист пуст и заполняется сканером). Пока подсчёт идёт, склад закрыт для продаж и перемещений; ответственный по умолчанию — директор компании склада.
Заголовки
| Заголовок | Значение | Описание |
|---|---|---|
Authorization | Bearer {token} | Токен из POST /common/auth/login |
Accept | application/json | Ответ в JSON |
Accept-Language | ru | Язык сообщений и названий: ru, uz, oz |
Тело запроса
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
company_id | integer | Да | Компания. ID существующей записи, доступной пользователю |
stock_id | integer | Да | Склад. ID существующей записи, доступной пользователю |
responsible_id | integer | Нет | Ответственный. ID существующей записи, доступной пользователю |
type | string | Да | Тип. Допустимые значения: partial, full |
category_ids | array | Нет | Категории. Макс. 1000 элементов |
category_ids[] | integer | Да | Категории. Без повторов |
product_ids | array | Нет | Товары. Макс. 1000 элементов |
product_ids[] | integer | Да | Товары. Без повторов |
comment | string | Нет | Комментарий. Макс. 5000 символов |
{
"company_id": 1,
"stock_id": 1,
"responsible_id": 2,
"type": "partial",
"comment": "Comment 3"
}curl -X POST "https://api.wasyt.uz/company/trade/inventory" \
-H "Accept: application/json" \
-H "Accept-Language: ru" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{"company_id":1,"stock_id":1,"responsible_id":2,"type":"partial","comment":"Comment 3"}'Ответ · 200
Поля ответа
| Поле | Тип | Описание |
|---|---|---|
company_id | integer | Компания |
stock_id | integer | Склад |
responsible_id | integer | Ответственный |
type | string | Тип |
comment | string | Комментарий |
updated_at | string | Обновлено |
created_at | string | Создано |
updater_id | integer | Обновитель |
amounts_diff_above | object | Избыток (сумма) |
amounts_diff_above.uzs | integer | |
amounts_diff_above.usd | integer | |
amounts_diff_above.eur | integer | |
amounts_diff_above.rub | integer | |
amounts_diff_below | object | Недосдача (сумма) |
amounts_diff_below.uzs | integer | |
amounts_diff_below.usd | integer | |
amounts_diff_below.eur | integer | |
amounts_diff_below.rub | integer | |
creator_id | integer | Создатель |
id | integer | ID |
{
"company_id": 1,
"stock_id": 1,
"responsible_id": 2,
"type": "partial",
"comment": "Comment 3",
"updated_at": "2026-09-30 12:54:16",
"created_at": "2026-09-30 12:54:16",
"updater_id": 2,
"amounts_diff_above": {
"uzs": 0,
"usd": 0,
"eur": 0,
"rub": 0
},
"amounts_diff_below": {
"uzs": 0,
"usd": 0,
"eur": 0,
"rub": 0
},
"creator_id": 2,
"id": 3
}
