feat: WPF-приложение для автоматизации оформления деклараций
- Чтение СПРАВКИ из Excel (ClosedXML), поддержка нескольких файлов - Группировка по ТН ВЭД: схлопывание строк с суммированием кол-ва/веса/суммы - Автоназначение кодов деклараций по справочнику ТН ВЭД (87 пар) - Цветовая маркировка: зелёный/жёлтый/красный по уровню уверенности - Самообучение: ручной выбор кода сохраняется в tnved_codes.json - Формирование Лист3 с разворачиванием строк по рег. номерам (ключевая функция) - Экспорт Лист2 + Лист3 в Excel
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using DeclarationAutomatization.Models;
|
||||
|
||||
namespace DeclarationAutomatization.Services;
|
||||
|
||||
public class CodeLookupService
|
||||
{
|
||||
private readonly RulesPersistenceService _persistence;
|
||||
private List<CodeLookupEntry> _entries;
|
||||
|
||||
public CodeLookupService(RulesPersistenceService persistence)
|
||||
{
|
||||
_persistence = persistence;
|
||||
_entries = _persistence.Load();
|
||||
}
|
||||
|
||||
public void Reload() => _entries = _persistence.Load();
|
||||
|
||||
// Назначает декларационные коды всем позициям в списке.
|
||||
public void AssignCodes(IEnumerable<DeclarationItem> items)
|
||||
{
|
||||
foreach (var item in items)
|
||||
AssignCode(item);
|
||||
}
|
||||
|
||||
private void AssignCode(DeclarationItem item)
|
||||
{
|
||||
var entry = _entries.FirstOrDefault(e => e.TnVed == item.TnVed);
|
||||
|
||||
if (entry == null || entry.Codes.Count == 0)
|
||||
{
|
||||
item.DeclarationCode = "";
|
||||
item.Confidence = ConfidenceLevel.Missing;
|
||||
item.CandidateCodes = new List<string>();
|
||||
return;
|
||||
}
|
||||
|
||||
if (entry.Codes.Count == 1)
|
||||
{
|
||||
item.DeclarationCode = entry.Codes[0];
|
||||
item.Confidence = ConfidenceLevel.Auto;
|
||||
item.CandidateCodes = new List<string>(entry.Codes);
|
||||
return;
|
||||
}
|
||||
|
||||
// Несколько кодов — неоднозначность
|
||||
item.CandidateCodes = new List<string>(entry.Codes);
|
||||
|
||||
// Эвристика: если у позиции есть рег. номер — предпочесть 9000
|
||||
if (!string.IsNullOrEmpty(item.RegNumber) && entry.Codes.Contains("9000"))
|
||||
{
|
||||
item.DeclarationCode = "9000";
|
||||
item.Confidence = ConfidenceLevel.Auto;
|
||||
}
|
||||
else
|
||||
{
|
||||
item.DeclarationCode = entry.Codes[0]; // первый = наиболее вероятный
|
||||
item.Confidence = ConfidenceLevel.Review;
|
||||
}
|
||||
}
|
||||
|
||||
// Фиксирует ручной выбор кода декларантом
|
||||
public void LearnFromManualEdit(string tnVed, string chosenCode)
|
||||
{
|
||||
_persistence.LearnCode(_entries, tnVed, chosenCode);
|
||||
}
|
||||
|
||||
public List<CodeLookupEntry> GetAllEntries() => _entries;
|
||||
}
|
||||
Reference in New Issue
Block a user