food-market/docs/pos-moysklad-reference.md
nns 81085aed8b
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
build(pos): сборка Win/Linux + AppImage, документация, скриншоты
- deploy/pos-publish.sh: self-contained Windows x64 (zip) + Linux x64 (tar.gz) +
  AppImage (если есть appimagetool); VERSION.txt для автообновления.
- docs/pos.md — инструкция кассиру/администратору (установка, горячие клавиши,
  смена, продажа, возврат, весы, печать, офлайн, фискализация-позже, автообновление).
- docs/pos-moysklad-reference.md — сверка розничной модели с МойСклад.
- docs/pos-progress.md — честный статус 11/11 пунктов + замеры + известные огранич.
- docs/pos-screenshots/ — 20 кадров (1920×1080 + 1366×768) + index.html галерея.
- .gitignore: сборки кассы (deploy/pos-dist) и TestResults — не в git.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 04:59:06 +05:00

4.1 KiB
Raw Permalink Blame History

Касса МойСклад — reference для POS food-market

Сверка перед проектированием кассы (задача владельца). Источник: https://dev.moysklad.ru/doc/api/remap/1.2/documents/ — розничные документы. Скрейп через headless Playwright (tests/e2e, chromium): SPA МойСклада грузит разделы по фрагменту нестабильно (часть якорей → «Файл не найден»), поэтому ниже — сводка модели по известной семантике МойСклада + успешно считанные разделы (внесение/выплата денег). Нам нужна не калька API, а поведение кассы.

Сущности розницы (МойСклад)

  • Розничная смена retailshift — открывается на точке продаж (ККМ/retailStore). Поля: open/close (bool), proceedsCash/proceedsNoCash (выручка нал/безнал), balanceStart (размен), balanceEnd, суммы продаж/возвратов. Пока смена открыта — к ней привязываются продажи/возвраты/внесения/выплаты.
  • Розничная продажа retaildemand — чек. Привязан к смене (retailShift) и точке. Оплата: cashSum (нал) + безнал; позиции positions (товар, цена, кол-во, скидка).
  • Возврат розничной продажи retailsalesreturn — возврат покупателю, со ссылкой на исходную продажу (demand) или без неё, нал/безнал, частичный.
  • Внесение денег retaildrawercashin — приход наличных в кассу ККМ внутри смены (размен/инкассация внутрь). Увеличивает наличные в ящике.
  • Выплата денег retaildrawercashout — изъятие наличных из кассы ККМ (инкассация наружу/расход). Уменьшает наличные в ящике.

Деньги и остатки

  • Касса = balanceStart (размен) + Σ продаж нал − Σ возвратов нал + Σ внесений − Σ выплат.
  • Безнал (карта) идёт на эквайринг/расчётный счёт отдельно.
  • Закрытие смены: фиксируется факт наличных; расхождение (излишек/недостача) видно в отчёте.
  • X-отчёт — промежуточный (без закрытия), Z-отчёт — при закрытии смены.

Как ложится на food-market

  • У нас уже есть серверный модуль «Деньги» с точно такой моделью (движения смены материализуются при закрытии — см. docs/money.md). POS НЕ дублирует эту логику:
    • смену открывает/закрывает через POST api/money/shifts/open|{id}/close;
    • внесение/выплату — POST api/money/shifts/{id}/drawer (In/Out);
    • продажи уходят батчем в api/pos/v1/sales (идемпотентно), сервер создаёт RetailSale (Posted), привязанный к открытой смене точки; возвраты — так же (IsReturn + ReferenceSaleId);
    • остаток кассы/эквайринга и Z-отчёт считает сервер (api/money/reports, api/money/shifts/{id}/report).
  • Весовой товар: МойСклад — weighed; у нас Packaging=2 (весовой). Весовой ШК с префиксом 20–29 парсит POS локально (код товара + вес/цена).
  • Фискализация (ОФД KZ) — отдельно; в POS только интерфейс-заглушка IFiscalProvider.