feat: единый файл Лист1+СПРАВКА, фильтры, сортировка, живой п/п

- Загрузка одного .xlsx (СПРАВКА + Лист1 в одном файле)
- Рег. номера берутся из СПРАВКА автоматически, группируются по (ТН ВЭД, Страна)
- Отдельный опциональный справочник кодов (CodesImportService)
- Фильтры: Все / Авто / Проверить / Нет кода / Без нетто
- Таблица сразу отсортирована по ТН ВЭД с живым обновлением п/п
- Начальный п/п: поле в UI, автоинкремент после экспорта
- Лист2: рамки, жёлтая строка при >1 рег. номере, итого по кол-ву
- Лист3: ТН ВЭД в колонке B вместо константы 09035
- Красный ErrorMessage под кнопкой загрузки, удалён SpravkaFileEntry
This commit is contained in:
Dianaka123
2026-04-07 11:47:31 +03:00
parent addf55e3b2
commit 697ae44519
13 changed files with 602 additions and 429 deletions
@@ -1,56 +1,41 @@
using System.Collections.Generic;
using System.Linq;
using DeclarationAutomatization.Models;
namespace DeclarationAutomatization.Services;
public class Sheet3ExpandService
{
// Строит строки Листа3, разворачивая позиции по регистрационным номерам.
// Группировка по ТН ВЭД: все рег. номера с таким же ТН ВЭД из СПРАВКИ.
public List<Sheet3Row> Expand(
IEnumerable<DeclarationItem> declarationItems,
IEnumerable<SpravkaItem> allSpravkaItems)
// Разворачивает позиции Листа2 по рег. номерам.
// Один товар с N рег. номерами → N строк в Листе3 (с тем же п/п).
public List<Sheet3Row> Expand(IEnumerable<DeclarationItem> items)
{
// Индекс: ТнВэд → уникальные (РегНомер, Дата)
var regByTnVed = allSpravkaItems
.Where(s => !string.IsNullOrWhiteSpace(s.RegNumber))
.GroupBy(s => s.TnVed)
.ToDictionary(
g => g.Key,
g => g
.Select(s => (s.RegNumber, s.RegDate))
.Distinct()
.ToList()
);
var result = new List<Sheet3Row>();
foreach (var item in declarationItems)
foreach (var item in items)
{
if (regByTnVed.TryGetValue(item.TnVed, out var regPairs) && regPairs.Count > 0)
{
foreach (var (regNum, regDate) in regPairs)
{
result.Add(new Sheet3Row
{
SequentialNumber = item.SequentialNumber,
ClassifierCode = "09035",
RegNumber = regNum,
RegDate = regDate,
});
}
}
else
if (item.RegEntries.Count == 0)
{
result.Add(new Sheet3Row
{
SequentialNumber = item.SequentialNumber,
ClassifierCode = "09035",
TnVed = item.TnVed,
RegNumber = "",
RegDate = "",
});
}
else
{
foreach (var entry in item.RegEntries)
{
result.Add(new Sheet3Row
{
SequentialNumber = item.SequentialNumber,
TnVed = item.TnVed,
RegNumber = entry.Number,
RegDate = entry.Date,
});
}
}
}
return result;