From 025d468492c7b0571ba48d9388e176346d79742c Mon Sep 17 00:00:00 2001 From: nns Date: Fri, 9 Oct 2026 15:08:15 +0500 Subject: [PATCH] =?UTF-8?q?fix(migration):=20=D0=B4=D0=B8=D0=B7=D0=B0?= =?UTF-8?q?=D0=BC=D0=B1=D0=B8=D0=B3=D1=83=D0=B0=D1=86=D0=B8=D1=8F=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=B2=D1=82=D0=BE=D1=80=D1=8F=D1=8E=D1=89=D0=B8=D1=85?= =?UTF-8?q?=D1=81=D1=8F=20=D0=BD=D0=BE=D0=BC=D0=B5=D1=80=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=BF=D1=80=D0=B8=D1=91=D0=BC=D0=BE=D0=BA=20(=D0=9C=D0=BE?= =?UTF-8?q?=D0=B9=D0=A1=D0=BA=D0=BB=D0=B0=D0=B4=20=D0=B4=D1=83=D0=B1=D0=BB?= =?UTF-8?q?=D0=B8=D1=80=D1=83=D0=B5=D1=82=20=D0=BF=D0=BE=20=D0=B3=D0=BE?= =?UTF-8?q?=D0=B4=D0=B0=D0=BC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Номера МойСклада повторяются по годам, а у нас (OrganizationId, Number) уникален → дубли роняли импорт. Сохраняем оригинальный номер где можно, при коллизии — «<номер>-<год>[-N]». Оригинал всегда в MoySkladExternalId. Co-Authored-By: Claude Opus 5.5 --- .../MoySklad/MoySkladDocumentImportService.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/food-market.infrastructure/Integrations/MoySklad/MoySkladDocumentImportService.cs b/src/food-market.infrastructure/Integrations/MoySklad/MoySkladDocumentImportService.cs index b4f6614..393b0d1 100644 --- a/src/food-market.infrastructure/Integrations/MoySklad/MoySkladDocumentImportService.cs +++ b/src/food-market.infrastructure/Integrations/MoySklad/MoySkladDocumentImportService.cs @@ -70,6 +70,16 @@ private static DateTime MomentToUtc(string? moment) .Select(p => new { p.Id, p.MoySkladExternalId }).ToDictionaryAsync(x => x.MoySkladExternalId!, x => x.Id, ct); var done = (await _db.Supplies.Where(s => s.MoySkladExternalId != null) .Select(s => s.MoySkladExternalId!).ToListAsync(ct)).ToHashSet(); + // Номера приёмок МойСклада ПОВТОРЯЮТСЯ по годам, а у нас (OrganizationId, Number) + // уникален. Сохраняем оригинальный номер где можно, при коллизии добавляем год/счётчик. + var usedNumbers = (await _db.Supplies.Select(s => s.Number).ToListAsync(ct)).ToHashSet(StringComparer.OrdinalIgnoreCase); + string UniqueNumber(string baseName, int year) + { + if (usedNumbers.Add(baseName)) return baseName; + var withYear = $"{baseName}-{year}"; + if (usedNumbers.Add(withYear)) return withYear; + for (var n = 2; ; n++) { var cand = $"{baseName}-{year}-{n}"; if (usedNumbers.Add(cand)) return cand; } + } // expand=positions (НЕ positions.assortment — это раскрывает весь товар и делает // страницу гигантской/зависающей). assortment.meta.href в позиции есть и так — из него @@ -86,10 +96,11 @@ private static DateTime MomentToUtc(string? moment) : fallbackSupplier ?? throw new InvalidOperationException("Нет контрагента-поставщика"); var momentUtc = MomentToUtc(d.Moment); var posted = d.Applicable; + var baseNumber = string.IsNullOrWhiteSpace(d.Name) ? $"МС-{d.Id[..8]}" : d.Name!; var supply = new foodmarket.Domain.Purchases.Supply { OrganizationId = orgId, - Number = string.IsNullOrWhiteSpace(d.Name) ? $"МС-{d.Id[..8]}" : d.Name!, + Number = UniqueNumber(baseNumber, momentUtc.Year), Date = momentUtc, Status = posted ? foodmarket.Domain.Purchases.SupplyStatus.Posted : foodmarket.Domain.Purchases.SupplyStatus.Draft, SupplierId = supplierId,