projects/org/pirotehnika/app/ozon/design/RULES.md

Правила ценообразования OZON

Версия: 3.0.0
Дата: 2025-11-30
Статус: УТВЕРЖДЕНО


КЛЮЧЕВЫЕ ПАРАМЕТРЫ

Параметр Значение Описание
OZON забирает 60% Комиссия + реклама + скидки клиентам
Нам остаётся 40% Выплата от цены
Целевая маржа 30% От выплаты (12% от цены)
Доставка 350₽ realFBS (Почта России)
Делитель 0.28 0.40 × 0.70

ПОРОГИ

Параметр Минимум Описание
min_price 1200₽ Защита от акций OZON
price 1600₽ Минимальная цена продажи

ФОРМУЛА ЦЕНЫ

              СЕБЕСТОИМОСТЬ + ДОСТАВКА
ЦЕНА = ─────────────────────────────────
                    0.28

Округление: вверх до 50₽
Минимум: 1600₽

ИСТОЧНИК ДАННЫХ — NocoDB

URL: https://91.218.142.168:8443
Проект: infra/nocodb-products/

Все данные ведутся в NocoDB. Excel только для импорта/экспорта.


РАСЧЁТ СЕБЕСТОИМОСТИ

Уровень 1: Загрузка прайс-листа

При загрузке прайса от поставщика:

  1. Базовая скидка прайса — по умолчанию для всех товаров
  2. Исключение по категории — переопределяет базовую
  3. Исключение по артикулу — высший приоритет
def get_cost(base_price, pricelist, article, category):
    # 1. Исключение по артикулу (приоритет)
    exc = find_exception(pricelist, 'article', article)
    if exc:
        return exc.fixed_price or base_price * (1 - exc.discount/100)

    # 2. Исключение по категории
    exc = find_exception(pricelist, 'category', category)
    if exc:
        return exc.fixed_price or base_price * (1 - exc.discount/100)

    # 3. Базовая скидка прайса
    return base_price * (1 - pricelist.base_discount/100)

Уровень 2: Формулы NocoDB

После загрузки себестоимости, цены считаются автоматически:

price_base = MAX(
    CEIL(({price_cost} + 350) / 0.28 / 50) * 50,
    1600
)

price_min = MAX(1200, ROUND({price_base} * 0.85))

price_old = ROUND({price_base} * 1.25)

СЕБЕСТОИМОСТЬ ПО ПОСТАВЩИКАМ

Поставщик Базовая скидка Примечание
JF (Joker) 50% Основной
Maxsem 50% Основной
Стрелецкий 50%
Салют Люкс 55%
УПЗ (Урал) 60%

НАБОРЫ

Артикулы наборов: -xN, -uN, -kN, -Nшт

СЕБЕСТ_НАБОРА = СЕБЕСТ_БАЗОВОГО × КОЛИЧЕСТВО

Примеры:
- 0920-x10 → себест(0920) × 10
- JF-B07-x03 → себест(JF-B07) × 3


7 ЦЕН

# Поле Тип Описание
1 price_cost Number Себестоимость (загружается)
2 price_min Formula Минимальная (защита от акций)
3 price_base Formula Наша цена продажи
4 price_old Formula Зачёркнутая (для скидки)
5 price_promo Number После акций OZON (от API)
6 price_bonus Number Со скидкой за бонусы (от API)
7 price_card Number По карте Озон (от API)

АКЦИИ OZON

Настройка Значение Описание
auto_action_enabled ENABLED Разрешаем акции
min_price Защита OZON не опустит ниже

Логика: Разрешаем акции, но min_price защищает от убытка.


ПРОВЕРКА МАРЖИ

Выплата = ЦЕНА × 0.40
Прибыль = Выплата - Себест - Доставка
Маржа = Прибыль / Выплата × 100%

Целевая маржа: 30% от выплаты (≈12% от цены)


ПРИМЕР РАСЧЁТА

Товар: Бенгальские огни 0920
База: 218₽
Поставщик: Maxsem (50%)

1. Себестоимость:
   СЕБЕСТ = 218 × 0.50 = 109

2. Цена:
   raw = (109 + 350) / 0.28 = 1639
   ЦЕНА = CEIL(1639 / 50) × 50 = 1650

3. Минимальная:
   MIN_PRICE = MAX(1200, 1650 × 0.85) = 1403

4. Старая:
   OLD_PRICE = 1650 × 1.25 = 2063

Проверка:

Выплата: 1650 × 0.40 = 660
Расходы: 109 + 350 = 459
Прибыль: 660 - 459 = 201
Маржа: 201 / 660 = 30.5% 

СТРУКТУРА ДАННЫХ

См. подробнее: DATA_STRUCTURE.md

Ключевые таблицы

Таблица Назначение
Brands Бренды/Производители
Suppliers Поставщики (юрлица)
Categories Категории товаров
PriceList Загруженные прайсы
PriceListException Исключения (скидки)
Products Товары PIM
ChannelProducts Товары на каналах
ChannelPrices Цены на каналах
ChannelPriceRules Правила расчёта

СКРИПТЫ

# Расчёт цен (только отчёт)
python price_reform.py

# Расчёт + загрузка в OZON
python price_reform.py --apply

# Синхронизация с NocoDB
python sync_nocodb.py

# Анализ продаж
python weekly_sales_analysis.py

ИСТОРИЯ ИЗМЕНЕНИЙ

Версия Дата Изменения
1.0 2025-11-29 Начальная версия
2.0 2025-11-30 Новая формула (делитель 0.28)
3.0 2025-11-30 Добавлен NocoDB, формулы, исключения

Версия: 3.0.0
Утверждено: 2025-11-30