| | | 1 | | namespace OzonRepositories.Data; |
| | | 2 | | |
| | | 3 | | /// <summary> |
| | | 4 | | /// Выбор Ozon MarketPrefix для группы et_producers (realId) с учётом справочника Manufacturers. |
| | | 5 | | /// </summary> |
| | | 6 | | public static class EtProducerMarketPrefixResolver |
| | | 7 | | { |
| | 13 | 8 | | public sealed record ProducerRow(int Id, int RealId, string Prefix, string? MarketPrefix); |
| | | 9 | | |
| | 25 | 10 | | public sealed record ManufacturerRow(int? EtProduserId, string Code, string? Name); |
| | | 11 | | |
| | | 12 | | public static string? Resolve( |
| | | 13 | | ProducerRow match, |
| | | 14 | | IReadOnlyList<ProducerRow> allProducers, |
| | | 15 | | IReadOnlyList<ManufacturerRow> manufacturers) |
| | | 16 | | { |
| | 3 | 17 | | var canonicalRealId = match.RealId != 0 ? match.RealId : match.Id; |
| | | 18 | | |
| | 3 | 19 | | var linkedManufacturer = manufacturers |
| | 5 | 20 | | .Where(m => m.EtProduserId == canonicalRealId && !string.IsNullOrWhiteSpace(m.Code)) |
| | 3 | 21 | | .OrderBy(m => PreferCanonicalManufacturer(m)) |
| | 3 | 22 | | .ThenBy(m => m.Code, StringComparer.OrdinalIgnoreCase) |
| | 3 | 23 | | .FirstOrDefault(); |
| | | 24 | | |
| | 3 | 25 | | if (linkedManufacturer != null) |
| | | 26 | | { |
| | 3 | 27 | | return linkedManufacturer.Code.Trim(); |
| | | 28 | | } |
| | | 29 | | |
| | 0 | 30 | | var producersById = allProducers.ToDictionary(p => p.Id); |
| | 0 | 31 | | var groupPrefixes = CollectGroupMarketPrefixes(allProducers, canonicalRealId); |
| | 0 | 32 | | if (groupPrefixes.Count == 0) |
| | | 33 | | { |
| | 0 | 34 | | return match.MarketPrefix?.Trim(); |
| | | 35 | | } |
| | | 36 | | |
| | 0 | 37 | | var manufacturerCodes = manufacturers |
| | 0 | 38 | | .Where(m => !string.IsNullOrWhiteSpace(m.Code)) |
| | 0 | 39 | | .Select(m => m.Code.Trim()) |
| | 0 | 40 | | .ToHashSet(StringComparer.OrdinalIgnoreCase); |
| | | 41 | | |
| | 0 | 42 | | var knownInManufacturers = groupPrefixes |
| | 0 | 43 | | .Where(p => manufacturerCodes.Contains(p)) |
| | 0 | 44 | | .ToList(); |
| | | 45 | | |
| | 0 | 46 | | if (knownInManufacturers.Count > 0) |
| | | 47 | | { |
| | 0 | 48 | | var alternate = knownInManufacturers |
| | 0 | 49 | | .Where(p => !string.Equals(p, match.Prefix, StringComparison.OrdinalIgnoreCase)) |
| | 0 | 50 | | .OrderBy(PreferCanonicalCode(manufacturers)) |
| | 0 | 51 | | .ThenBy(p => p, StringComparer.OrdinalIgnoreCase) |
| | 0 | 52 | | .ToList(); |
| | | 53 | | |
| | 0 | 54 | | if (alternate.Count > 0) |
| | | 55 | | { |
| | 0 | 56 | | return alternate[0]; |
| | | 57 | | } |
| | | 58 | | |
| | 0 | 59 | | return knownInManufacturers |
| | 0 | 60 | | .OrderBy(PreferCanonicalCode(manufacturers)) |
| | 0 | 61 | | .ThenBy(p => p, StringComparer.OrdinalIgnoreCase) |
| | 0 | 62 | | .First(); |
| | | 63 | | } |
| | | 64 | | |
| | 0 | 65 | | if (match.RealId != 0 && producersById.TryGetValue(match.RealId, out var headProducer)) |
| | | 66 | | { |
| | 0 | 67 | | return headProducer.MarketPrefix?.Trim() ?? match.MarketPrefix?.Trim(); |
| | | 68 | | } |
| | | 69 | | |
| | 0 | 70 | | return match.MarketPrefix?.Trim(); |
| | | 71 | | } |
| | | 72 | | |
| | | 73 | | private static List<string> CollectGroupMarketPrefixes(IReadOnlyList<ProducerRow> allProducers, int canonicalRealId) |
| | | 74 | | { |
| | 0 | 75 | | return allProducers |
| | 0 | 76 | | .Where(p => p.Id == canonicalRealId || p.RealId == canonicalRealId) |
| | 0 | 77 | | .Select(p => p.MarketPrefix?.Trim()) |
| | 0 | 78 | | .Where(p => !string.IsNullOrWhiteSpace(p)) |
| | 0 | 79 | | .Distinct(StringComparer.OrdinalIgnoreCase) |
| | 0 | 80 | | .ToList()!; |
| | | 81 | | } |
| | | 82 | | |
| | | 83 | | private static int PreferCanonicalManufacturer(ManufacturerRow row) => |
| | 3 | 84 | | string.Equals(row.Code, row.Name, StringComparison.OrdinalIgnoreCase) ? 0 : 1; |
| | | 85 | | |
| | | 86 | | private static Func<string, int> PreferCanonicalCode(IReadOnlyList<ManufacturerRow> manufacturers) => |
| | 0 | 87 | | code => manufacturers.Any(m => |
| | 0 | 88 | | string.Equals(m.Code, code, StringComparison.OrdinalIgnoreCase) && |
| | 0 | 89 | | string.Equals(m.Code, m.Name, StringComparison.OrdinalIgnoreCase)) |
| | 0 | 90 | | ? 0 |
| | 0 | 91 | | : 1; |
| | | 92 | | } |