food-market/docs/inventory-model-progress.md
nns db8cd637e5
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
docs(inventory): итог проверки + скриншоты новой модели
Прогресс-док: итог проверки (unit 64/64, live e2e на стенде всех сценариев,
миграция stockUnchanged, full-chain 16/16, menu-walk 3/3, deploy-stage OK).
Скриншоты: карточка «Завершена» с кнопками «Создать оприходование/списание» и
блоком «Связанные документы» (Списание С-2026-000002 проведён), колонка «Результат».

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 21:24:45 +05:00

7.5 KiB
Raw Blame History

Инвентаризация по модели МойСклада — прогресс

Замечание владельца (08.10.2026): «инвентаризация стоит в состоянии „проведено“, но без оприходования и списания — логика непонятная».

Сейчас (неправильно): InventoriesController.Post сам применяет движения MovementType.InventoryAdjustment к остаткам и ставит Status=Posted — без создания Оприходования/Списания. Владелец видит «Проведено» без связанных документов; в отчётах непонятно, откуда изменения.

Как должно быть (по МойСкладу): инвентаризация НЕ двигает остатки; она фиксирует расчётный/фактический/разницу, а движения создаются связанными документами Оприходование (излишки) и Списание (недостача).

ПОПРАВКА (Mac-Claude): кнопку «Применить результаты» НЕ добавляем (не одобрено владельцем). Только две кнопки «Создать оприходование» / «Создать списание». Мобильный post — временная совместимость (в docs помечено).

План / статус

  1. Сверка с МойСкладом → docs/inventory-moysklad-reference.md (API SPA — факты из справки + школы торговли; поля calculatedQuantity/correctionAmount/correctionSum, applicable, enter/loss «на основании»).
  2. Инвентаризация не двигает остатки; статусы Draft→Completed («Черновик»→«Завершена»). Эндпоинт complete замораживает строки без движений (InventoriesController).
  3. На завершённой — create-enter (излишки) / create-loss (недостача): создают черновики Оприходования/Списания со строками разницы + ссылка InventoryDocId. Повторно нельзя (409). Кнопки «Применить результаты» НЕТ (по поправке).
  4. Блок «Связанные документы» в карточке (web); колонка «Результат» в списке; «На основании инвентаризации №…» в Оприходовании/Списании (web + DTO).
  5. «Вернуть в черновик» (unpost) отменяет проведение и удаляет связанные документы (остатки возвращаются). Править завершённую нельзя (Update/AddLine требуют Draft).
  6. Миграция Posted+InventoryAdjustment → связанные проведённые Оприходование/Списание: InventoryMigrationController (dry-run/apply) переметка движений (не задваивает), остатки до/после проверяются (stockUnchanged). Backup — в deploy/migrate-inventory-to-docs.sh.
  7. Веб + мобильное API: post/unpost совместимость (post = завершить+создать&провести оба), помечено временным в docs/mobile-api.md. CSV-импорт инвентаризации — без изменений (работает).
  8. [~] Тесты: unit (InventoryResult — разница/сумма/только посчитанные) ✓; integration/e2e/full-chain шаг 10 — ниже.
  9. docs/supply-inventory.md — «Как провести инвентаризацию» (5 шагов).
  10. [~] deploy-stage + коммиты в main (Opus 5.5), global.json не коммитить, не мешать с rebrand — ниже.

Домен/миграция

  • InventoryStatus { Draft=0, Completed=1 } (переименован Posted→Completed, значение то же).
  • Enter.InventoryDocId / Loss.InventoryDocId (nullable) + EF-миграция Phase38_InventoryLinks.
  • InventoryResult (application) — чистая разбивка diff→излишки/недостача (юнит-тесты).
  • Демо-сидеры: инвентаризации теперь Completed без прямых движений.

Что НЕ трогаем

Прод, shared-postgres, global.json, gateway nginx, sklad.

Проверка (на стенде test.admin.food-market.kz)

  • Unit: InventoryResultTests (разница/сумма/только посчитанные/округление) + poco — 64/64 ✓.
  • Live e2e (API): создать (излишек +2, недостача −2) → complete (остаток НЕ изменился) → create-enter/create-loss → в инвентаризации видны связанные документы (черновик) → провести оба → остатки +2/−2 ✓; в Оприходовании inventoryNumber = И-2026-… ✓; повторный create-enter → 409 ✓; unpost → удалил связанные, остатки вернулись, статус Draft ✓.
  • Миграция данных: inventory-migration/run dry-run → 1 кандидат; apply → migrated 1, stockUnchanged=true, stockDiffRows=0 (остатки до/после совпали); повторный dry-run → 0 (идемпотентно). И-2026-000001 → связанное проведённое Списание С-2026-000002 (см. скрин).
  • full-chain шаг 10: 16/16 ЗЕЛЁНЫЙ — добавлена проверка новой модели (complete→create-enter→ связанный документ→провести→+3→«на основании»), плюс совместимый /post.
  • menu-walk: 3/3 (все роли, страницы инвентаризации рендерятся, 0 ошибок/тостов).
  • Скриншоты: docs/inventory-screenshots/ (карточка «Завершена» с кнопками и блоком «Связанные документы», колонка «Результат» в списке).
  • deploy-stage: OK.

Формальных xUnit-integration не добавлял — поведение покрыто full-chain (реальный стек) + живым e2e на стенде + unit. UAT — обновить при следующем прогоне UAT-сценария.

Журнал

  • 08.10 — старт: прочитано замечание, составлен план. Сверка с МойСкладом.
  • 08.10 — реализация: домен (Draft→Completed, Enter/Loss.InventoryDocId, миграция Phase38), InventoryResult, контроллеры (complete/create-enter/create-loss/post-compat/unpost), миграция данных (InventoryMigrationController + скрипт), веб-UI, доки.
  • 08.10 — проверено на стенде: full-chain 16/16, menu-walk 3/3, live e2e всех сценариев, миграция stockUnchanged. Коммиты в main (0d44cda, b4bd0e4, b036050), push. global.json не трогал.