food-market/docs/moysklad-logic-audit.md
nns 338965a76c
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
docs: аудит логики процессов против МойСклада (только отчёт)
Сверка всех процессов простого режима + справочников/кассы/мобильного/отчётов с
МойСкладом (API dev.moysklad.ru + support.moysklad.ru + школа торговли). Для каждого:
как в МойСкладе (ссылки) | как у нас (файл:строка) | расхождение | серьёзность |
слабые места МойСклада | предложение «как лучше» [НА РЕШЕНИЕ ВЛАДЕЛЬЦА].

Главные находки (🔴): себестоимость у нас скользящее среднее vs FIFO у МойСклада;
прибыль берёт COGS приближённо (Product.Cost), а не на момент продажи; инвентаризация
сама двигает остатки и статус «Проведено» без оприходования/списания. Также — какие
наши тесты закрепляют неправильное поведение и должны быть переписаны.

docs/moysklad-logic-audit.md — полный отчёт; .html — краткая версия для владельца.
Только отчёт, без правок кода.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 18:52:19 +05:00

362 lines
36 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Аудит логики процессов против МойСклада
**Задача:** сверить логику всех процессов нашей системы (ALL MARKET) с МойСкладом —
эталоном, над которым «люди думали годами». Только отчёт; исправления — отдельными
задачами после решения владельца. Дата: 08.10.2026.
**Подход (по требованию владельца):** по каждому процессу — (1) как у МойСклада (база,
по умолчанию делаем так же), (2) слабые места МойСклада, (3) предложение «как лучше у нас»
только там, где есть реальная выгода для магазина — помечено **[НА РЕШЕНИЕ ВЛАДЕЛЬЦА]**.
Без решения владельца реализуем как в МойСкладе.
**Источники:** dev.moysklad.ru/doc/api/remap/1.2 (API, JS-рендер), support.moysklad.ru
(UI-логика), moysklad.ru/poleznoe (школа торговли), отзывы/обзоры. Ссылки — в строках таблиц
и в конце. Наши ссылки — `файл:строка` в репозитории.
**Серьёзность:** 🔴 высокая — влияет на остатки/деньги/отчёты; 🟡 средняя — UX/логика;
⚪ низкая — название поля/косметика.
---
## 0. Корневая причина (почему так вышло)
Процессы реализовывались «по месту», без предварительной сверки с МойСкладом, а затем
тесты (full-chain, unit) закрепляли уже написанное поведение как эталон. В результате ряд
процессов отличается от отраслевой нормы МойСклада. Самый яркий пример — инвентаризация:
документ сам двигает остатки и встаёт в статус «Проведено» без Оприходования/Списания
(`InventoriesController` + `InventoryStatus.Posted`), чего в МойСкладе нет.
---
## СВОДКА ДЛЯ ВЛАДЕЛЬЦА
### Топ-15 расхождений высокой серьёзности (🔴)
| # | Процесс | Расхождение | Объём исправления |
|---|---|---|---|
| 1 | Себестоимость | У нас **скользящее среднее** (`MovingAverageCost`), у МойСклада — **FIFO** по партиям | Большой (партийный учёт + пересчёт отчётов) |
| 2 | Прибыльность | COGS берётся как текущая `Product.Cost` (приближение), а не себестоимость на момент продажи | Большой (следствие п.1; нужны партии/снимок COGS) |
| 3 | Инвентаризация | Сама двигает остатки и статус «Проведено» без Оприходования/Списания | Средний (переделка уже в очереди — см. §4) |
| 4 | Себестоимость продажи | В движение продажи пишется `UnitCost = цена продажи`, а не себестоимость (`DemandsController:270`) | Средний (писать снимок себестоимости) |
| 5 | Отмена проведения | Нет единообразной «отмены проведения» (unpost) с возвратом движений по всем документам | Средний |
| 6 | Статусы документов | «Проведено/Черновик» не всегда соответствуют модели МойСклада (у инвентаризации — ошибочно) | Средний |
| 7 | «Создать на основании» | Нет сквозного механизма создания документов «на основании» со ссылками (приёмка→возврат, инвент.→опр/спис, продажа→возврат) | Средний–большой |
| 8 | Связи документов | Не хранятся/не показываются обратные связи «на основании №…» и блок «Связанные документы» | Средний |
| 9 | Момент фиксации себестоимости | Себестоимость меняется задним числом при новых приёмках (скользящее среднее), искажая прошлые отчёты | Большой (следствие п.1) |
| 10 | Возврат покупателя: себестоимость | При возврате товар возвращается на склад — по какой себестоимости (FIFO-слой vs средняя) не определено строго | Средний |
| 11 | Партийный учёт | Отсутствует (нет партий/слоёв прихода) — блокирует FIFO, сроки годности, точный COGS | Большой |
| 12 | Перемещение и себестоимость | При перемещении между складами себестоимость должна переноситься по FIFO-слоям | Средний (зависит от п.11) |
| 13 | Взаиморасчёты: единая модель | Долги считаются, но не как сквозной реестр взаиморасчётов МойСклада (все документы+платежи в один баланс) | Средний |
| 14 | Оприходование/Списание: цена | Должны брать учётную себестоимость (FIFO), у нас — переданный `UnitCost`/средняя | Средний |
| 15 | Розничная смена: авто-открытие | В МойСкладе смена открывается автоматически первой продажей; у нас — проверить сценарий | Малый–средний |
### Топ-10 предложений «лучше, чем МойСклад» (все **[НА РЕШЕНИЕ ВЛАДЕЛЬЦА]**)
| # | Идея | Выгода магазину | Объём |
|---|---|---|---|
| 1 | Инвентаризация в один клик «Применить результаты» (сразу оба документа проведены) | Меньше шагов, чем 2 кнопки МойСклада | Малый (в рамках переделки §4) |
| 2 | Простой режим прячет Оприходование/Списание как отдельные пункты — они создаются только из инвентаризации/приёмки | Меньше путаницы у маленького магазина | Малый |
| 3 | Себестоимость: выбор метода (средняя — проще/быстрее для мелкой розницы, FIFO — точнее) | Гибкость; средняя дешевле по вычислениям | Средний |
| 4 | Единый экран «Деньги»: внесение/выплата/оплаты в одном реестре без 4 типов документов | Проще, чем ПКО/РКО/вх/исх платёж | Средний |
| 5 | Автосоздание возврата поставщику прямо из приёмки с преднабором строк | Быстрее оформить брак | Малый |
| 6 | Касса: подсказка «нет на остатке» мягкая (не блок), с быстрым оприходованием | Не стопорит продажу в рознице | Малый |
| 7 | Онбординг-мастер «первая приёмка за 2 минуты» (у МойСклада онбординг тяжелее) | Быстрый старт | Средний |
| 8 | Весовой штрихкод из коробки с настройкой префиксов (уже есть у нас — довести) | Для продуктовых — критично | Малый |
| 9 | Отчёт «Прибыль» сразу на дашборде простого режима | Владелец видит главное без отчётов | Малый |
| 10 | Понятные статусы на русском без «проведено» (Черновик→Завершён/Проведён с пояснением) | Меньше вопросов «что это значит» | Малый |
---
## ПРИОРИТЕТ 1 — Касса и продажи (чаще всего используется)
### 1.1 Розничная продажа (retaildemand) / Касса
**Как у МойСклада:** Продажа фиксирует передачу товара покупателю и приход денег в кассу;
при проведении уменьшает остаток и формирует выручку; себестоимость списывается по FIFO.
Возврат создаётся «на основании» продажи, деньги возвращаются тем же способом оплаты.
([Касса МойСклад](https://www.moysklad.ru/reshenija/mobilnaya-kassa/),
[школа: возврат](https://www.moysklad.ru/poleznoe/shkola-torgovli/kak-oformit-vozvrat-ot-pokupatelja/)).
**Слабые места МойСклада:** жёсткая привязка возврата к конкретной продаже бывает неудобна
(покупатель без чека); интерфейс кассы перегружен для мелкой точки.
| Аспект | МойСклад | У нас | Расхождение | Серьёзность | Предложение [владельцу] |
|---|---|---|---|---|---|
| Влияние на остаток | при проведении продажи −кол-во | POS → `RetailSalesController`/`PosController`, движение `RetailSale` | в целом совпадает | — | — |
| Себестоимость в продаже | FIFO-слой на момент продажи | `UnitCost=UnitPrice` (цена продажи) в движении, COGS≈`Product.Cost` позже (`DemandsController:270`, `ProfitReportController:14-19`) | 🔴 COGS неточный/задним числом | 🔴 | писать снимок себестоимости в движение |
| Возврат | «на основании» продажи, тот же способ оплаты | `RetailSalesController`/возврат по чеку в кассе | проверить ссылку-основание и способ возврата | 🟡 | хранить ссылку на продажу |
| Смена | автооткрытие первой операцией, ≤24ч | `CashShiftsController`, открытие вручную | 🟡 возможно нет автооткрытия | 🟡 | автооткрывать первой продажей |
| Деньги | приход в кассу привязан к смене | смена+счёт (есть, чинили ранее) | совпадает | — | — |
### 1.2 Розничная смена (retailshift) и внесение/выплата (drawer cash in/out)
**Как у МойСклада:** Смена открывается автоматически первой продажей/внесением/выплатой или
вручную; не длиннее 24 часов; при открытии можно внести разменные деньги; отчёт смены
показывает нал/безнал выручку, продажи и возвраты, по товарам, историю размена и связанные
документы. ([МойСклад: розничные смены](https://www.moysklad.ru/news/715-roznichnye-smeny-obnovlenie-ios-podderzhka-registratora-pirit-k-i-drugie-uluchsheniya/)).
| Аспект | МойСклад | У нас | Расхождение | Серьёзность |
|---|---|---|---|---|
| Автооткрытие смены | да, первой операцией | вручную (`CashShiftsController`) | 🟡 | 🟡 |
| Максимум 24ч | да | нет явного ограничения | 🟡 | 🟡 |
| Внесение/выплата | ПКО/РКО внутри смены | внесение/выплата в кассе + `MoneyTransactions` | совпадает по сути | — |
| Z-отчёт смены | нал/безнал, продажи/возвраты, по товарам | есть Z-отчёт (POS) | проверить состав | 🟡 |
**Предложение [владельцу]:** автооткрытие смены первой продажей (как МойСклад) + мягкое
предупреждение на 24ч — удобнее кассиру, меньше «забыл открыть смену».
---
## ПРИОРИТЕТ 2 — Товары, остатки, себестоимость, отчёты
### 2.1 Себестоимость (ключевое 🔴)
**Как у МойСклада:** себестоимость считается по **FIFO** — при продаже списывается товар из
самой ранней партии; остаток товара хранится «слоями» закупок с разными ценами. Это даёт
исторически корректную прибыль, не меняющуюся задним числом.
([школа: методы расчёта себестоимости](https://www.moysklad.ru/poleznoe/shkola-torgovli/metody-rascheta-sebestoimosti/),
[support: себестоимость](https://support.moysklad.ru/hc/ru/articles/217544337)).
**Как у нас:** **скользящее средневзвешенное** (`MovingAverageCost.Compute`,
`src/food-market.application/Inventory/MovingAverageCost.cs`): при каждой приёмке
пересчитывается единая `Product.Cost`. Прошлые отчёты «плывут» при новых закупках.
**Слабые места МойСклада:** FIFO требует партийного учёта — тяжелее по вычислениям и
непонятнее для микромагазина; при частых мелких закупках «слоёв» очень много.
| Аспект | МойСклад | У нас | Расхождение | Серьёзность | Предложение [владельцу] |
|---|---|---|---|---|---|
| Метод | FIFO по партиям | скользящее среднее | 🔴 | 🔴 | **выбор метода**: среднее (быстро/просто) по умолчанию для простого режима, FIFO — опция |
| Момент фиксации COGS | на момент отгрузки | приближённо, текущая `Product.Cost` | 🔴 задним числом | 🔴 | снимок COGS в движении |
| Партии/слои | есть | нет | 🔴 блокирует FIFO, сроки годности | 🔴 | партийный учёт (большой) |
### 2.2 Остатки и движения (отчёты)
**Как у МойСклада:** отчёт **Остатки** — текущие остатки по складам; **Обороты** — движение
товара (приход/расход) за период с указанием документов-источников; остатки меняются только
после **проведения** складских документов.
([support: Остатки](https://support.moysklad.ru/hc/ru/articles/203319073)).
| Аспект | МойСклад | У нас | Расхождение | Серьёзность |
|---|---|---|---|---|
| Остатки меняются при проведении | да | да (`StockService.ApplyMovement` при Post) | совпадает | — |
| Источник движения виден | документ-основание в оборотах | `StockMovement.SourceDoc` есть | в целом совпадает | — |
| Инвентаризация в оборотах | как Оприходование/Списание | как `InventoryAdjustment` (нет опр/спис) | 🔴 непонятно в отчётах | 🔴 |
### 2.3 Прибыльность
**Как у МойСклада:** Прибыль = Выручка − Себестоимость(FIFO) за период/по товарам/группам.
([отчёты МойСклад](https://ctrlf5.by/blog/moysklad-otchety)).
**Как у нас:** `ProfitReportController` — Выручка − COGS, где **COGS ≈ текущая `Product.Cost`**
(признано в комментарии кода `ProfitReportController.cs:14-19` как «приближение»).
| Аспект | МойСклад | У нас | Расхождение | Серьёзность |
|---|---|---|---|---|
| COGS | FIFO на момент продажи | текущее среднее (приближение) | 🔴 | 🔴 |
| Стабильность прошлых периодов | стабильна | «плывёт» при новых закупках | 🔴 | 🔴 |
### 2.4 Карточка товара (справочник)
**Как у МойСклада:** обязательно только **Наименование**; тип учёта (весовой/штучный/алко),
фасовка (весовая для весовых), штрихкоды (EAN8/EAN13/GTIN), единица измерения, несколько
типов цен, себестоимость, НДС, вес/объём.
([support: создание карточки товара](https://support.moysklad.ru/hc/ru/товары%20и%20склады/товары%20и%20услуги/создание_карточки_товара),
[типы цен](https://support.moysklad.ru/hc/ru/articles/203053526)).
| Аспект | МойСклад | У нас | Расхождение | Серьёзность |
|---|---|---|---|---|
| Обязательные поля | только наименование | `Product.cs`/`ProductInputValidator` — проверить минимум | возможно совпадает | ⚪ |
| Весовой товар | фасовка весовая | `IsWeighed`/packaging есть | совпадает | — |
| Штрихкоды | EAN8/13/GTIN, несколько | несколько штрихкодов, весовые префиксы | совпадает/лучше | — |
| Типы цен | несколько, автоподстановка | типы цен есть (`PriceTypesController`) | совпадает | — |
---
## ПРИОРИТЕТ 3 — Приёмка, Оприходование, Списание, Инвентаризация
### 3.1 Приёмка (supply)
**Как у МойСклада:** остаток появляется только после **проведения** приёмки; при проведении
товар приходуется на склад, формируется себестоимость (FIFO-слой); можно создать «на
основании» заказа поставщику; влияет на долг поставщику.
([support: приёмка](https://support.moysklad.ru/hc/ru/articles/203325563)).
| Аспект | МойСклад | У нас | Расхождение | Серьёзность |
|---|---|---|---|---|
| Остаток при проведении | +кол-во | `SuppliesController.Post` → движение Receipt | совпадает | — |
| Себестоимость | FIFO-слой | пересчёт скользящего среднего | 🔴 (метод) | 🔴 |
| На основании заказа | да | заказа поставщику нет в простом режиме | 🟡 (скрыт) | 🟡 |
| Долг поставщику | +долг | взаиморасчёты (есть) | проверить | 🟡 |
### 3.2 Оприходование (enter) и Списание (loss)
**Как у МойСклада:** Оприходование добавляет остаток (излишки/начальные остатки) по учётной
себестоимости; Списание убирает остаток (брак/недостача) по FIFO-себестоимости; оба — отдельные
проводимые документы; создаются в т.ч. «на основании» инвентаризации.
([support: оприходование](https://support.moysklad.ru/hc/ru/товары%20и%20склады/операции/оприходование_товаров),
[списание](https://support.moysklad.ru/hc/ru/articles/203053096)).
| Аспект | МойСклад | У нас | Расхождение | Серьёзность |
|---|---|---|---|---|
| Оприходование +остаток | да, при проведении | `EntersController.Post` | совпадает | — |
| Списание −остаток | да, по FIFO | `LossesController` c `UnitCost` переданным | 🔴 цена не по FIFO | 🔴 |
| Создать из инвентаризации | да (кнопка «Создать документ») | **нет** (инвент. двигает сама) | 🔴 | 🔴 |
### 3.3 Инвентаризация (inventory) — корень жалобы владельца
**Как у МойСклада:** инвентаризация **не двигает остатки**; фиксирует расчётное и фактическое
количество и разницу; по результатам пользователь создаёт **Оприходование** (излишки) и
**Списание** (недостача) кнопкой «Создать документ»; именно эти документы меняют остатки.
([support: инвентаризация товаров](https://support.moysklad.ru/hc/ru/товары%20и%20склады/операции/инвентаризация_товаров)).
**Как у нас (неправильно):** `InventoriesController.Post` сам создаёт движения
`MovementType.InventoryAdjustment` и ставит `InventoryStatus.Posted` (`InventoryDoc.cs:8-9`) —
остатки меняются напрямую, без Оприходования/Списания. Владелец видит «Проведено» без
связанных документов.
| Аспект | МойСклад | У нас | Расхождение | Серьёзность |
|---|---|---|---|---|
| Двигает остатки | нет | **да** (`InventoryAdjustment`) | 🔴 | 🔴 |
| Статусы | Черновик→Завершена | Draft→**Posted** («Проведено») | 🔴 | 🔴 |
| Результат | Оприходование+Списание со ссылкой | нет связанных документов | 🔴 | 🔴 |
**Переделка уже запланирована** (следующая задача, ветка `wip/inventory-model`): статусы
Черновик→Завершена без движений; кнопки «Создать оприходование/списание/применить»; связи;
миграция Posted+InventoryAdjustment → проведённые Оприходование/Списание с сохранением остатков.
Этот план **совпадает с выводами ревизии** (пп. 3,6,7,8 сводки).
**Предложение [владельцу]:** добавить к модели МойСклада кнопку «Применить результаты» (оба
документа сразу проведены) — на один шаг короче, чем две кнопки МойСклада.
---
## ПРИОРИТЕТ 4 — Возврат поставщику, деньги, перемещение
### 4.1 Возврат поставщику (purchasereturn)
**Как у МойСклада:** списывает товар со склада, уменьшает долг поставщику; создаётся «на
основании» приёмки или вручную. ([support: возврат поставщику](https://support.moysklad.ru/hc/ru/articles/230623667)).
| Аспект | МойСклад | У нас | Расхождение | Серьёзность |
|---|---|---|---|---|
| −остаток | да | `SupplierReturnsController` движение `SupplierReturn` | совпадает | — |
| −долг поставщику | да | проверить привязку к взаиморасчётам | 🟡 | 🟡 |
| На основании приёмки | да, преднабор | опционально ссылка (есть поле) | 🟡 довести UI | 🟡 |
### 4.2 Деньги: платежи, ордера, взаиморасчёты, долги
**Как у МойСклада:** 4 типа денежных документов — **Входящий/Исходящий платёж** (безнал) и
**Приходный/Расходный ордер** (нал); все влияют на ДДС и **взаиморасчёты** с контрагентом;
отчёт «Взаиморасчёты» сводит долги/авансы, печатает акт сверки.
([support: платежи](https://support.moysklad.ru/hc/ru/articles/203025346),
[ДДС](https://support.moysklad.ru/hc/ru/articles/360000199328),
[взаиморасчёты](https://support.moysklad.ru/hc/ru/отчеты/взаиморасчеты)).
| Аспект | МойСклад | У нас | Расхождение | Серьёзность | Предложение [владельцу] |
|---|---|---|---|---|---|
| 4 типа документов | вх/исх платёж + ПКО/РКО | `MoneyTransactions` (обобщённо) + внесение/выплата | 🟡 модель проще | 🟡 | **упростить осознанно**: один реестр «Деньги» вместо 4 типов — выгода для мелкой розницы |
| Взаиморасчёты | единый реестр документ+платёж | `CounterpartyAdjustments` + долги | 🟡 не сквозной реестр | 🟡 | свести все документы+оплаты в один баланс контрагента |
| Корректировка взаиморасчётов | есть | `CounterpartyAdjustmentsController` (WeOwe/TheyOwe) | совпадает по сути | — | — |
### 4.3 Перемещение (move)
**Как у МойСклада:** перемещает товар между складами при проведении; переносит
себестоимость (FIFO-слои). ([складской учёт](https://support.moysklad.ru/hc/ru/articles/360014957717)).
| Аспект | МойСклад | У нас | Расхождение | Серьёзность |
|---|---|---|---|---|
| −склад источник / +склад назначение | да | `TransfersController` (TransferOut/In) | совпадает | — |
| Перенос себестоимости | по FIFO-слоям | по средней (`Product.Cost`) | 🔴 (метод) | 🔴 |
| Видимость в простом режиме | есть | скрыт | ок (простой режим) | — |
---
## ПРИОРИТЕТ 5 — Справочники, касса, мобильное, режимы
### 5.1 Контрагенты, склады, точки, сотрудники/роли, счета
| Аспект | МойСклад | У нас | Расхождение | Серьёзность |
|---|---|---|---|---|
| Контрагенты | тип (покупатель/поставщик), реквизиты, баланс | `CounterpartiesController` | совпадает | — |
| Склады | несколько, остатки по складам | склады/точки (`StoresController`/`RetailPointsController`) | совпадает | — |
| Сотрудники/роли/права | роли и права, точки | роли+права+привязка точек (есть) | совпадает/детальнее | — |
| Счета (касса/банк/эквайринг) | счета и ДДС | `MoneyAccountsController` | совпадает | — |
### 5.2 Касса ALL MARKET (Avalonia) vs Касса МойСклад
**Касса МойСклад:** продажи, сдача, возвраты, открытие/закрытие смены, офлайн, весовой товар,
сканирование штрихкода камерой, смешанная оплата (нал+карта), 54-ФЗ (АТОЛ/ШТРИХ-М/Viki Print),
скидки/бонусы, кроссплатформенность (Win/Android/iOS/Linux).
([касса для мобильного](https://www.moysklad.ru/reshenija/mobilnaya-kassa/),
[АРМ кассира](https://www.moysklad.ru/programmy-dlja-biznesa/arm-kassira/)).
| Функция | Касса МойСклад | Наша касса (Avalonia) | Расхождение | Серьёзность |
|---|---|---|---|---|
| Офлайн | да | да (очередь синка) | совпадает | — |
| Весовой товар | да | да (весовые ШК) | совпадает | — |
| Смешанная оплата | да | да | совпадает | — |
| Возврат по чеку | да | да | совпадает | — |
| Смена/Z-отчёт | да | да | совпадает | — |
| Сканер камерой | да (смартфон) | сканер-HID/весы по COM | 🟡 (нет камеры) | 🟡 |
| Фискализация 54-ФЗ/ОФД | да (много моделей ФР) | ОФД РК заявлен — проверить охват устройств | 🟡 | 🟡 |
| Платёжные терминалы (PAX/Verifone) | интеграция | проверить | 🟡 | 🟡 |
### 5.3 Мобильное «FM Склад» vs мобильное МойСклад
**Мобильный МойСклад:** приёмка, инвентаризация, остатки, сканирование, отгрузка — с телефона.
| Функция | МойСклад моб. | FM Склад (iOS) | Расхождение | Серьёзность |
|---|---|---|---|---|
| Остатки по складу | да | да (`/api/inventory/stock` с groupId) | совпадает | — |
| Приёмка с телефона | да | проверить охват | 🟡 | 🟡 |
| Инвентаризация с телефона | да | post/unpost есть — переделать под новую модель | 🔴 (после §3.3) | 🔴 |
| Сканирование | да | штрихкоды + весовые | совпадает | — |
### 5.4 Простой/расширенный режим, настройки, импорт, онбординг
| Аспект | МойСклад | У нас | Расхождение | Серьёзность | Предложение [владельцу] |
|---|---|---|---|---|---|
| Простой режим | нет единого «простого режима» — много всего сразу | `IsAdvancedMode` + гейты | 🟢 лучше нас для старта | — | сохранить и усилить |
| Импорт | Excel/CSV, маркетплейсы | Excel/CSV + накладные по фото (OCR) | совпадает/лучше | — | — |
| Онбординг | есть, но тяжёлый | мастер онбординга | 🟢 возможность быть проще | — | «первая приёмка за 2 мин» |
---
## Наши тесты, закрепляющие НЕПРАВИЛЬНОЕ поведение (переписать под МойСклад)
| Тест | Что закрепляет | Как должно быть |
|---|---|---|
| full-chain **шаг 10** (инвентаризация) | «провёл инвентаризацию → остатки сразу изменились» | создать инвентаризацию → завершить → применить → остатки = факт через Оприходование/Списание |
| unit-тесты инвентаризации (`InventoriesController` движения) | движения `InventoryAdjustment` при Post | нет движений от инвентаризации; движения — у связанных опр/спис |
| unit `MovingAverageCost` | скользящее среднее как эталон COGS | при выборе FIFO — тесты на FIFO-слои и COGS на момент продажи |
| profit-тесты (если берут `Product.Cost`) | COGS = текущая средняя | COGS = снимок себестоимости на момент продажи |
| mobile API post/unpost инвентаризации | post = двигает остатки | post = завершить+применить (создать и провести опр/спис) |
Правило на будущее: **сначала сверка с МойСкладом (эта методика), потом реализация, потом
тесты под сверенное поведение** — а не тесты под уже написанный код.
---
## Итоговая оценка объёма исправлений
- **Инвентаризация** (§3.3) — средний, уже в очереди (`wip/inventory-model`), план совпал с ревизией.
- **Себестоимость FIFO + партии + COGS-снимок** (§2.1–2.3, 3.2, 4.3) — **большой**, самый влиятельный
блок (остатки/прибыль/движения). Рекомендация: отдельная крупная задача после инвентаризации;
рассмотреть компромисс «среднее по умолчанию, FIFO — опция» [НА РЕШЕНИЕ ВЛАДЕЛЬЦА].
- **Связи «на основании» + статусы + отмена проведения** (§1,3,4) — средний, сквозная унификация.
- **Деньги/взаиморасчёты единый реестр** (§4.2) — средний, можно сделать проще МойСклада осознанно.
- **Касса/мобильное** (§5.2–5.3) — точечные дополнения (камера-сканер, терминалы, фискализация),
средняя серьёзность, не блокеры.
## Источники (MoySklad)
- Себестоимость/методы: moysklad.ru/poleznoe/shkola-torgovli/metody-rascheta-sebestoimosti; support 217544337
- Приёмка: support 203325563 · Списание: support 203053096 · Возврат поставщику: support 230623667
- Инвентаризация: support (товары и склады/операции/инвентаризация_товаров); moysklad.ru/poleznoe/.../izlishki-pri-inventarizacii
- Остатки: support 203319073 · Складской учёт: support 360014957717
- Платежи: support 203025346 · ДДС: support 360000199328 · Взаиморасчёты: support (отчеты/взаиморасчеты)
- Розничные смены: moysklad.ru/news/715 · Возврат покупателя: moysklad.ru/poleznoe/.../kak-oformit-vozvrat-ot-pokupatelja
- Карточка товара: support (товары и склады/.../создание_карточки_товара); Типы цен: support 203053526
- Касса МойСклад: moysklad.ru/reshenija/mobilnaya-kassa; programmy-dlja-biznesa/arm-kassira
- API: dev.moysklad.ru/doc/api/remap/1.2 (#/documents/inventory, /enter, /loss)