Commit graph

7 commits

Author SHA1 Message Date
nns 9506f9edc8 perf(migration): резюм документов по offset (не перечитывать уже перенесённое)
startOffset у всех документных импортов + эндпоинт ?offset=N: при продолжении
пропускаем уже перенесённые через offset API (а не перечитывая сотни страниц).
Идемпотентный skip по msId держит границу.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:52:28 +05:00
nns 0c9d20a469 feat(migration): мигратор оприходований/списаний/возвратов поставщику/розничных продаж
По проверенному шаблону приёмок (идемпотентно по msId, резюмируемо, МСК→UTC, тиыны,
дизамбигуация номеров, SaveChanges по документу, движения остатков):
- enter (+остаток), loss (−остаток, WriteOff), purchasereturn (−остаток, SupplierReturn),
  retaildemand (−остаток, RetailSale; оплата нал/безнал из cashSum/noCashSum, кассир=owner).
- Общие помощники LoadMaps/Aggregate. Эндпоинт POST /import-supplies?type=enter|loss|
  purchasereturn|retaildemand (фон, job с нужным kind).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:34:36 +05:00
nns 025d468492 fix(migration): дизамбигуация повторяющихся номеров приёмок (МойСклад дублирует по годам)
Номера МойСклада повторяются по годам, а у нас (OrganizationId, Number) уникален →
дубли роняли импорт. Сохраняем оригинальный номер где можно, при коллизии —
«<номер>-<год>[-N]». Оригинал всегда в MoySkladExternalId.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:08:15 +05:00
nns 955c3f5e77 fix(migration): очищать ChangeTracker при ошибке документа (стоп каскада сбоев)
Сбой SaveChanges одного документа оставлял сущности tracked → все последующие
падали (каскад), импорт застревал. Теперь в catch — ChangeTracker.Clear().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:53:05 +05:00
nns 6fdc9e527a fix(migration): приёмки — сохранение по одному документу + агрегация позиций по товару
Батч из 50 приёмок с общим товаром давал дубль строки stocks (ApplyMovementAsync
создавал новую строку, не видя ещё не сохранённую). Теперь: SaveChanges после КАЖДОГО
документа (следующий видит закоммиченные остатки) + агрегация позиций по товару в
документе (средневзвешенная цена) + ChangeTracker.Clear (не копим граф на 7k докумов).
Идемпотентно по msId — повторный запуск продолжает с места.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:31:27 +05:00
nns f2a1493ea0 fix(migration): лёгкий expand для документов (positions, не positions.assortment) + таймаут 130с
Тяжёлый expand=positions.assortment раскрывал весь товар в каждой позиции → страница
гигантская и зависала. assortment.meta.href в позиции есть и без раскрытия. Таймаут
HttpClient МойСклада поднят до 130с (страница иногда > 100с).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:07:54 +05:00
nns 2ed9f04cb2 feat(migration): документный мигратор МойСклад (приёмки) + externalId на документах
Part 2 (документы) — проверенный шаблон на приёмках:
- Phase41: MoySkladExternalId у counterparties/stores/units/retail_points/employees и
  документов (supplies/enters/losses/inventories/supplier_returns/retail_sales/
  cash_shifts/money_transactions) + индексы. Свойства на доменных сущностях.
- MoySkladClient.StreamDocumentsAsync: документы в хронологии (order=moment,asc), expand
  позиций/связей (limit=100), обработка 429/сбоев.
- MoySkladDocumentImportService.ImportSuppliesAsync: идемпотентно по msId, резюмируемо
  (skip перенесённых), moment МСК→UTC, суммы из тиынов, поставщик по externalId контрагента,
  товары по externalId, проведение → движения остатков (StockService). Журнал ошибок.
- Импорт контрагентов теперь пишет MoySkladExternalId (нужно для ссылок в документах).
- Эндпоинт POST /api/admin/moysklad/import-supplies (фон, job). Остальные типы — по шаблону.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:53:52 +05:00