Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker API / Build + push API (push) Waiting to run
Docker API / Deploy API on stage (push) Blocked by required conditions
Docker Web / Build + push Web (push) Waiting to run
Docker Web / Deploy Web on stage (push) Blocked by required conditions
Решение владельца 08.10: продавать/списывать в минус РАЗРЕШЕНО, но с постоянным предупреждением и требованием провести инвентаризацию. - Снята блокировка «недостаточно остатка» (409 oversell): розница, касса (POS-синк), опт-отгрузка, списание, перемещение, возврат поставщику, отмена приёмки. Деньги (минус счёта) — по-прежнему запрещены (другое правило). - NegativeStockAlert (сущность + миграция Phase39): создаётся/обновляется при уходе остатка < 0 (единая точка — StockService), авто-закрытие при возврате ≥ 0. Частичный уникальный индекс: один открытый алерт на (org, store, product). Причина: тип/номер документа/автор/время. - API /api/negative-stock: список (с подсказкой «возможно, не проведена приёмка П-…»), /count (для баннеров), /recount (черновик инвентаризации по минусам склада). Отчёт «Остатки» — фильтр negativeOnly. - Веб: постоянный баннер «N товаров в минусе — нужна инвентаризация» (сворачивается, крестиком не закрыть) + «Пересчитать эти товары»; в остатках — красная пометка и фильтр «Только минусы». - Тесты: integration 2/2 (минус разрешён → алерт → recount → авто-закрытие; фильтр); full-chain шаг 9/13 переписаны (oversell/отмена приёмки → проведено + предупреждение). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
56 lines
6.1 KiB
Markdown
56 lines
6.1 KiB
Markdown
# Уведомления об отрицательных остатках → инвентаризация
|
||
|
||
Идея владельца 08.10.2026: «когда у товара количество становится отрицательным, система и
|
||
мобильное приложение должны отправлять PUSH о том, что необходимо произвести инвентаризацию
|
||
по таким товарам, и сразу предоставить список таких товаров».
|
||
|
||
Решение владельца 08.10: **разрешать продажу в минус нужно**, но с постоянным предупреждением
|
||
везде (касса, админка, приложение) и требованием срочно провести инвентаризацию.
|
||
|
||
Поправка 09.10: **пункт 12 (предварительная себестоимость) НЕ делаем** — тема отложена;
|
||
себестоимость продаж в минус оставляем как сейчас, расчёт не трогаем.
|
||
|
||
## Сверка с МойСкладом (что есть у них)
|
||
- **Отчёт «Остатки»** (`report/stock`) с параметром `stockMode`: значения `all`, `positiveOnly`,
|
||
`negativeOnly`, `underminimum`, `nonEmpty`, `empty`. Т.е. отрицательные остатки — это **только
|
||
фильтр в отчёте** (`stockMode=negativeOnly`). Отдельного «уведомления» нет.
|
||
- **Вебхуки** МойСклада — на CRUD-события сущностей (создание/изменение/удаление документов и
|
||
справочников). Порога «остаток ушёл в минус» среди событий **нет** — вебхук на изменение
|
||
документа есть, но «стало отрицательно» как события нет.
|
||
- Минус **разрешён** настройкой («разрешить отрицательные остатки»); push/требования пересчёта нет.
|
||
|
||
**Вывод:** у МойСклада — пассивный отчёт-фильтр. Мы делаем **лучше**: проактивные предупреждения
|
||
(событие при уходе в минус), постоянные баннеры/индикаторы в кассе/админке/приложении, push
|
||
(web/telegram, APNs-заглушка), подсказка причины, и действие «Пересчитать» (авто-черновик
|
||
инвентаризации по минусовым товарам), с авто-закрытием при возврате остатка ≥ 0 и эскалацией.
|
||
(Источник по МойСкладу: dev.moysklad.ru/doc/api/remap/1.2 report/stock stockMode; webhooks — на сущности.)
|
||
|
||
## План / статус
|
||
0. [ ] Сверка с МойСкладом (отчёт/вебхуки/разрешение минуса).
|
||
1. [ ] Событие при проведении документа → остаток < 0: создать/обновить предупреждение
|
||
(товар, склад, остаток, документ-причина). Остаток ≥ 0 → закрыть автоматически.
|
||
2. [ ] Подсказка причины: есть непроведённая приёмка/черновик → «возможно, не проведена приёмка П-…».
|
||
3. [ ] Без спама: агрегация (1 уведомление/склад/N мин, по умолч. 15), тихие часы, получатели
|
||
Администратор + Кладовщики склада, вкл/выкл в настройках орг и профиле.
|
||
4. [ ] Действие «Пересчитать эти товары»: черновик инвентаризации по складу с этими товарами.
|
||
5. [ ] Каналы: веб (колокольчик + центр уведомлений + Web Push/VAPID), Telegram (бот),
|
||
мобильное API (GET /api/notifications, read, создать инвентаризацию), отчёт «Отрицательные».
|
||
APNs — только заглушка (device tokens + IPushSender), без платного Apple Dev.
|
||
6. [ ] Тесты unit/integration/e2e; деплой; скриншоты.
|
||
7. [ ] Снять блокировку продажи в минус: касса/POS-синк/офлайн, розница веб, опт, списание,
|
||
перемещение — проведение в минус РАЗРЕШЕНО (убрать 409 oversell; деньги — счёт в минус запрещён).
|
||
8. [ ] Касса: предупреждение в строке («на остатке 2 шт — уйдёт в минус»), жёлтый индикатор в шапке
|
||
«N товаров в минусе», офлайн по локальным остаткам.
|
||
9. [ ] Админка: постоянный баннер «N товаров в минусе — проведите инвентаризацию» + «Пересчитать»;
|
||
красная пометка в списках товаров/остатков.
|
||
10. [ ] Мобильное API/iOS: счётчик + список в /api/me или /api/notifications.
|
||
11. [ ] Эскалация: минус не закрыт за N часов (по умолч. 24) → повторное уведомление владельцу/админу;
|
||
на главной — «Просроченные минусы».
|
||
12. [~] ОТЛОЖЕНО (поправка владельца) — предварительная себестоимость НЕ делаем.
|
||
|
||
## Что НЕ трогаем
|
||
Прод, shared-postgres, global.json, gateway nginx, sklad. Расчёт себестоимости (п.12 отложен).
|
||
|
||
## Журнал
|
||
- 09.10 — старт: прогресс-док, сверка с МойСкладом, обследование кода.
|