food-market/docs/supply-inventory-mobile-progress.md
nns 05e7fdecef feat(s31): CameraScanner + scan-mode приёмки с last-purchase price (3/8)
CameraScanner (components/CameraScanner.tsx) — порт из sklad'a @zxing/
browser + @zxing/library. Непрерывное сканирование: окно не закрывается
между сканами, EAN13/EAN8/UPC/Code128/ITF. Подавление повтора 1.5с (в
кадре товар распознаётся десятки раз в секунду). Вибрация 40мс + flash
зелёный/красный + анимация scanPop/scanRing.

SupplyScanPage (/purchases/supplies/scan):
- Выбор поставщика (search по /counterparty-search), склада, валюты.
- Кнопка 'Сканировать камерой' → <CameraScanner /> на полный экран.
- Alt: аппаратный сканер — <input> в details-блоке, Enter = +1.
- Каждый скан: GET /product-by-barcode → если нашёлся, +1 к
  существующей строке или новая сверху. Цена подставляется last-
  purchase-price (из последней Posted supply-line по этому товару).
- Неизвестный штрихкод: feedback 'Нет в каталоге', вибрация ошибки.
  Товар создавать — отдельный переход на /products/new (future wiring).
- Прогресс сохраняется в localStorage ('fm.supply-scan.rows') —
  перезагрузка не теряет; очищается после успешного сохранения.
- Save → POST /api/purchases/supplies (существующий endpoint), статус
  Draft; редирект в /purchases/supplies/:id для проверки/проведения.

InvoicesController.ProductByBarcode теперь возвращает ещё и
lastPurchasePrice (из последней Posted supply-line).

@zxing/browser@0.1.5 + @zxing/library@0.23.0 добавлены в deps.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-10-04 21:36:41 +05:00

3.8 KiB
Raw Blame History

Supply + Inventory mobile — прогресс

Задача: добавить в food-market два мобильных варианта приёмки (по фото накладной + сканированием штрихкодов) и инвентаризацию с телефона с офлайн-режимом. Образец логики — ~/ref/sklad/sklad/ (read-only); но документы создаются в НАШЕЙ базе (Supply/Inventory), а не черновиками в МойСклад.

Все три фичи — основные (видны в простом режиме), доступны Admin + Storekeeper.

Чек-лист

Приёмка

  • 1. Приёмка по фото/PDF накладной — загрузка, фоновое распознавание через Claude CLI (claude -p --output-format json, промпт из ClaudeCliInvoiceExtractor.cs), запуск локально или через ssh на RemoteHost. Статусы: queued → extracting → review | failed. Платные API-ключи не заводим.
  • 2. Экран проверки накладной. Редактируемые строки, помощь в сопоставлении с товаром (barcode → saved-mapping → ручной), создание товара прямо из строки, проверка «итого», предложение создать контрагента. Коммит → наш Supply (Draft).
  • 3. Приёмка сканированием. Непрерывная камера, +1 к строке на скан, последняя закупочная подставляется, неизвестный штрихкод → предложить создать товар или отложить.

Инвентаризация

  • 4. Инвентаризация с телефона. Выбор склада + опц. группы, офлайн-каталог в IndexedDB, прогресс сохраняется локально; скан / ручной ввод; неизвестные штрихкоды в отдельный список.
  • 5. Расхождения видны сразу. Учёт/факт/дельта в шт. и в деньгах, фильтр «только расхождения». Частичная (по группе) НЕ обнуляет непосчитанные; полная — явный выбор.
  • 6. Учётный остаток подставляется автоматически (без ручной кнопки «Пересчитать»): при создании bookQty = текущий Stock; при добавлении позиции — тоже; перед проведением пересчёт + warning о расхождениях с момента создания (продажи/приёмки). Если где-то экспорт в МойСклад — там тоже явный расчётный остаток.

Общее

  • 7. Мобильная вёрстка 375×667 + PWA. Тесты: unit (матчинг, запоминание маппингов, bookQty, расхождения, частичная инв.), integration (накладная → Supply Draft; частичная инв. не трогает другие товары; bookQty = текущий Stock), e2e на стенде.
  • 8. ~/deploy-stage.sh, ретест, docs/supply-inventory.md — пользовательская инструкция.

Правила

НЕ трогать: ~/ref/sklad (только читать), прод admin.food-market.kz, global.json, gateway nginx, POS WPF.

После каждого пункта: build + тесты + коммит порцией + [x].