Система управління складськими залишками для e-commerce

Коли два покупці одночасно оформлюють останній екземпляр товару, без надійної системи залишків один із них дізнається про відсутність після оплати. Ми розробляємо систему управління складськими залишками, яка виключає overselling, автоматизує резервування та синхронізацію з обліковими системами. Реалізуємо проєкт під ключ — від аудиту до впровадження та подальшої підтримки, забезпечуючи стабільну роботу вашого e-commerce.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Система управління складськими залишками для e-commerce
Середній
~5 днів
Часті запитання

Зазначимо: коли два покупці одночасно кладуть у кошик останній екземпляр товару, перемагає той, хто швидше натиснув «Оформити замовлення». Без системи управління залишками другий отримає повідомлення про відсутність після оплати — це overselling. Ми будуємо механізми, які виключають такі ситуації: атомарне резервування, синхронізацію з обліковими системами та сповіщення про дефіцит. Нижче — технічні деталі, які дозволять вашій платформі працювати з реальними запасами, а не з цифрами в адмінці.

Проблеми, які вирішує система

Перша — конкурентне резервування. Якщо в момент оформлення замовлення не заблокувати одиницю, два користувачі можуть купити один товар. Друга — завислі резерви. Покинуті кошики — не рідкість, і якщо не звільняти резерви, через тиждень половина залишків буде недоступна. Третя — розсинхронізація із зовнішніми обліковими системами. Коли 1С або МійСклад оновлюють кількість, а магазин продовжує продавати за старими даними, виникають заборгованості.

Схема даних

Базова структура для PostgreSQL:

CREATE TABLE product_variants (
    id BIGSERIAL PRIMARY KEY,
    product_id BIGINT NOT NULL REFERENCES products(id),
    sku VARCHAR(100) NOT NULL UNIQUE,
    attributes JSONB NOT NULL DEFAULT '{}',
    stock_qty INTEGER NOT NULL DEFAULT 0,
    reserved_qty INTEGER NOT NULL DEFAULT 0,
    low_stock_threshold INTEGER NOT NULL DEFAULT 5,
    CHECK (stock_qty >= 0),
    CHECK (reserved_qty >= 0),
    CHECK (stock_qty >= reserved_qty)
);
CREATE TABLE stock_movements (
    id BIGSERIAL PRIMARY KEY,
    variant_id BIGINT NOT NULL REFERENCES product_variants(id),
    delta INTEGER NOT NULL,
    type VARCHAR(50) NOT NULL,
    reference VARCHAR(255),
    created_at TIMESTAMP NOT NULL DEFAULT NOW()
);

available_qty = stock_qty - reserved_qty обчислюється на льоту. Лог stock_movements фіксує кожну операцію для аудиту. Індекси на (product_id, sku) та (variant_id, created_at) прискорюють пошук і звітність.

Атомарне резервування без гонок

Атомарність забезпечується через UPDATE ... RETURNING:

UPDATE product_variants
SET reserved_qty = reserved_qty + :qty
WHERE id = :variant_id
  AND (stock_qty - reserved_qty) >= :qty
RETURNING id, stock_qty, reserved_qty;

Якщо рядок не повернувся — товару недостатньо. В Laravel це обгортається в транзакцію з lockForUpdate(). Для високонавантажених сценаріїв використовуйте песимістичне блокування рядка, щоб уникнути взаємоблокувань.

Чому важливо звільняти резерви?

Покинутий кошик — втрачений залишок. Два підходи: TTL через чергу (точність до хвилини) та scheduled cleanup (простіше, але ±5 хвилин). Для магазинів до 1000 замовлень на день достатньо cron-завдання кожні 5 хвилин. Порівняння методів:

Характеристика TTL через чергу Scheduled cleanup
Точність звільнення ±1 хвилина ±5 хвилин
Залежність від інфраструктури Потрібна черга (Redis/Beanstalkd) Тільки cron
Навантаження при 1000 замовлень/день Низька Низька
Як налаштувати TTL в Laravel?
// В сервіс-провайдері реєструємо job
use App\Jobs\ReleaseReservation;

$ttl = Carbon::now()->addMinutes(30);
ReleaseReservation::dispatch($variantId, $qty)->delay($ttl);

Якщо замовлення оформлено, job видаляється. Якщо ні — резерв автоматично зменшується.

Інтеграція з 1С та МійСклад

Залишки надходять із зовнішніх систем двома способами:

Режим Опис Коли вибрати
Webhook Склад викликає ваш endpoint при зміні Висока частота оновлень
Pull Магазин опитує систему раз на N хвилин Обмеження по безпеці

Важливе правило: при імпорті оновлюйте тільки stock_qty, не чіпаючи reserved_qty. Інакше активні резерви злетять.

Як відображати статус на вітрині?

Для покупця важливо бачити реальну наявність. Ми обчислюємо доступну кількість та відображаємо:

  • Якщо available_qty > low_stock_threshold — «В наявності».
  • Якщо 0 < available_qty ≤ low_stock_threshold — «Залишилось N шт.».
  • Якщо available_qty = 0 — «Немає в наявності».
  • Якщо налаштовано передзамовлення — «Під замовлення, 5–7 днів».

Для високонавантажених сторінок статус кешується в Redis з TTL 60 секунд.

Як налаштувати сповіщення про низький залишок?

Оповіщення менеджера закупівель тригериться при оновленні stock_qty нижче порогу. В Laravel це observer:

class ProductVariantObserver
{
    public function updated(ProductVariant $variant): void
    {
        if ($variant->wasChanged('stock_qty') && $variant->isLowStock()) {
            LowStockAlert::dispatch($variant);
        }
    }
}

Алерт надсилається в email, Telegram або Slack. Додатково можна налаштувати SMS для критичних позицій.

Як оптимізувати запити для відображення залишків?

При виведенні списку товарів типова помилка — N+1 запит: для кожного варіанту вибираємо залишок окремо. Використовуйте withCount або віконні функції. Наприклад, для PostgreSQL:

SELECT p.*, SUM(sm.delta) OVER (PARTITION BY sm.variant_id) AS current_stock
FROM products p
LEFT JOIN stock_movements sm ON sm.variant_id = p.id
WHERE ...

Цей запит виконується за один прохід. Для великих каталогів агрегуйте дані в Redis через scheduled job.

Процес впровадження

  1. Проектування схеми даних та вибір методів резервування.
  2. Реалізація атомарних операцій з тестуванням на конкурентність.
  3. Налаштування звільнення резервів (TTL або cron).
  4. Інтеграція із зовнішніми обліковими системами (1С, МійСклад).
  5. Розробка панелі адміністрування з фільтрами та експортом.
  6. Навантажувальне тестування та деплой.

До складу робіт входить: підготовка документації по схемі даних та API, передача вихідного коду та доступів до репозиторію, навчання адміністраторів роботі з панеллю, гарантійна підтримка протягом 30 днів після деплою.

Строки реалізації

Етап Час
Базове резервування + лог 3–5 днів
Інтеграція з обліковою системою +3–5 днів
Кешування та відображення на вітрині +2 дні
Панель залишків в адмінці +2–3 дні
Разом 1–2 тижні

Правильно спроектована система залишків знижує втрати від overselling на 15–20% та виключає ручний контроль. Наприклад, для магазину з 5000 замовлень на місяць усунення overselling зберігає до 150 000 гривень виручки щомісячно. Додатково автоматизація закупівель економить до 100 000 гривень на місяць на зарплаті логіста.

Зв'яжіться з нами для аудиту поточної схеми. Отримайте консультацію з архітектури вашого складу — замовте її просто зараз.

Наші компетенції:

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1394
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1369
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1142
  • Розробка веб-сайту для компанії ФІКСПЕР
    Розробка веб-сайту для компанії ФІКСПЕР
    1060