| | | 1 | | using System.Globalization; |
| | | 2 | | using OzonOrdersWeb.Areas.Studio2.ViewModels.ApiSupplierSettings; |
| | | 3 | | |
| | | 4 | | namespace OzonOrdersWeb.WebServices.ApiSettingsGrid; |
| | | 5 | | |
| | | 6 | | /// <summary>Вариант списка в колонке связи. <c>Groups</c> — значения зависимой колонки, при которых вариант доступен (п |
| | 17 | 7 | | public sealed record ApiMappingOption(string Value, string Label, IReadOnlyList<string>? Groups = null); |
| | | 8 | | |
| | | 9 | | /// <summary>Колонка связи «склад → значение поставщика»: <c>Field</c> — имя свойства строки формы.</summary> |
| | | 10 | | public sealed record ApiMappingColumn( |
| | | 11 | | string Field, |
| | | 12 | | string Header, |
| | | 13 | | IReadOnlyList<ApiMappingOption> Options, |
| | | 14 | | string? EmptyLabel, |
| | | 15 | | string? DependsOn = null, |
| | | 16 | | bool DisabledOnError = false, |
| | | 17 | | int MinWidth = 280); |
| | | 18 | | |
| | | 19 | | public sealed record ApiMappingRow(int WarehouseId, string WarehouseName, IReadOnlyDictionary<string, string> Values); |
| | | 20 | | |
| | | 21 | | /// <summary> |
| | | 22 | | /// Описание грида связей склада Studio2 со значениями API-поставщика (Armtek, ML-Auto, Профит-Лига, Berg). |
| | | 23 | | /// Значения уходят обычным POST формы страницы как <c><Prefix>[i].<Field></c>, контроллеры не меняются. |
| | | 24 | | /// </summary> |
| | | 25 | | public sealed record ApiMappingGrid( |
| | | 26 | | string Key, |
| | | 27 | | string Prefix, |
| | | 28 | | string Eyebrow, |
| | | 29 | | string Title, |
| | | 30 | | string Description, |
| | | 31 | | string AnchorPrefix, |
| | | 32 | | string? LoadError, |
| | | 33 | | bool PostWarehouseName, |
| | | 34 | | bool RowSave, |
| | | 35 | | IReadOnlyList<string> LinkedFields, |
| | | 36 | | IReadOnlyList<ApiMappingColumn> Columns, |
| | | 37 | | IReadOnlyList<ApiMappingRow> Rows); |
| | | 38 | | |
| | | 39 | | public static class ApiMappingGridBuilders |
| | | 40 | | { |
| | | 41 | | private static ApiMappingRow Row(int id, string name, params (string Field, string? Value)[] values) |
| | | 42 | | => new(id, name, values.ToDictionary(x => x.Field, x => x.Value ?? "")); |
| | | 43 | | |
| | | 44 | | public static ApiMappingGrid Armtek(ArmtekSettingsViewModel model) |
| | | 45 | | { |
| | | 46 | | var addresses = model.ArmtekBuyers |
| | | 47 | | .SelectMany(b => b.DeliveryAddresses.Select(a => (Buyer: b.Kunnr, Address: a.Kunnr, a.DisplayName))) |
| | | 48 | | .GroupBy(x => x.Address) |
| | | 49 | | .Select(g => new ApiMappingOption(g.Key, g.First().DisplayName, g.Select(x => x.Buyer).Distinct().ToList())) |
| | | 50 | | .ToList(); |
| | | 51 | | return new ApiMappingGrid( |
| | | 52 | | "dirApiMapArmtek", "DeliveryMappings", "Проценка Armtek", "Связи склада и адреса доставки", |
| | | 53 | | "Выберите клиента и адрес для склада. Без связи проценка работает по настройкам Armtek по умолчанию.", |
| | | 54 | | "armtek-mapping", model.DeliveryMappingsLoadError, true, true, |
| | | 55 | | ["BuyerKunnr", "DeliveryAddressKunnr"], |
| | | 56 | | [ |
| | | 57 | | new ApiMappingColumn("BuyerKunnr", "Клиент Armtek", |
| | | 58 | | model.ArmtekBuyers.Select(b => new ApiMappingOption(b.Kunnr, b.DisplayName)).ToList(), "Не связано") |
| | | 59 | | new ApiMappingColumn("DeliveryAddressKunnr", "Адрес доставки Armtek", addresses, "Не связано", DependsOn |
| | | 60 | | ], |
| | | 61 | | model.DeliveryMappings.Select(m => Row(m.ShipmentWarehouseId, m.WarehouseName, |
| | | 62 | | ("BuyerKunnr", m.BuyerKunnr), ("DeliveryAddressKunnr", m.DeliveryAddressKunnr))).ToList()); |
| | | 63 | | } |
| | | 64 | | |
| | | 65 | | public static ApiMappingGrid MlAuto(MlAutoSettingsViewModel model) => MlAutoCore( |
| | | 66 | | "dirApiMapMlAuto", "ПРОЦЕНКА ML-AUTO", "Выберите адрес ML-Auto для склада Studio2. Его можно изменить в корзине |
| | | 67 | | "Адрес доставки ML-Auto", "mlauto-mapping", model.DeliveryMappingsLoadError, model.DeliveryMappings, model.Deliv |
| | | 68 | | |
| | | 69 | | public static ApiMappingGrid MlAutoRu(MlAutoRuSettingsViewModel model) => MlAutoCore( |
| | | 70 | | "dirApiMapMlAutoRu", "ML-AUTO RU", "Выберите адрес ML-Auto RU для склада Studio2. Связи хранятся отдельно от ML- |
| | | 71 | | "Адрес доставки ML-Auto RU", "mlautoru-mapping", model.DeliveryMappingsLoadError, model.DeliveryMappings, model. |
| | | 72 | | |
| | | 73 | | private static ApiMappingGrid MlAutoCore(string key, string eyebrow, string description, string header, string ancho |
| | | 74 | | string? error, List<MlAutoDeliveryMappingViewModel> mappings, List<MlAutoDeliveryAddressViewModel> addresses) |
| | | 75 | | => new(key, "DeliveryMappings", eyebrow, "Связи склада и адреса доставки", description, anchor, error, true, tru |
| | | 76 | | ["DeliveryAddressId"], |
| | | 77 | | [new ApiMappingColumn("DeliveryAddressId", header, |
| | | 78 | | addresses.Select(a => new ApiMappingOption(a.Id, a.DisplayName)).ToList(), "Не связано", DisabledOnError |
| | | 79 | | mappings.Select(m => Row(m.ShipmentWarehouseId, m.WarehouseName, ("DeliveryAddressId", m.DeliveryAddressId)) |
| | | 80 | | |
| | | 81 | | public static ApiMappingGrid ProfitLiga(ProfitLigaSettingsViewModel model) => new( |
| | | 82 | | "dirApiMapProfitLiga", "PointMappings", "ЗАКАЗ ПРОФИТ-ЛИГИ", "Связи склада и торговой точки", |
| | | 83 | | "Выберите торговую точку Профит-Лиги для склада отгрузки Studio2. Точка определяет адрес доставки и дату поставк |
| | | 84 | | "profitliga-mapping", model.PointsLoadError, true, false, |
| | | 85 | | ["PointCode"], |
| | | 86 | | [new ApiMappingColumn("PointCode", "Торговая точка Профит-Лиги", |
| | | 87 | | model.Points.Select(p => new ApiMappingOption(p.Code, p.DisplayName)).ToList(), "Не связано", DisabledOnErro |
| | | 88 | | model.PointMappings.Select(m => Row(m.ShipmentWarehouseId, m.WarehouseName, ("PointCode", m.PointCode))).ToList( |
| | | 89 | | |
| | | 90 | | public static ApiMappingGrid Berg(BergSettingsViewModel model) => new( |
| | | 91 | | "dirApiMapBerg", "AddressMappings", "ЗАКАЗ ЧЕРЕЗ API BERG", "Адреса отгрузки Berg", |
| | | 92 | | "Заказ через API уходит на конкретный адрес из справочника Berg. Склад отгрузки заказа Studio2 определяет адрес: |
| | | 93 | | "berg-mapping", model.AddressesLoadError, false, false, |
| | | 94 | | ["BergShipmentAddressId"], |
| | | 95 | | [ |
| | | 96 | | new ApiMappingColumn("BergShipmentAddressId", "Адрес Berg", |
| | | 97 | | model.Addresses.Select(a => new ApiMappingOption(a.Id.ToString(CultureInfo.InvariantCulture), a.DisplayN |
| | | 98 | | "— не связан —", DisabledOnError: true), |
| | | 99 | | new ApiMappingColumn("DispatchType", "Тип отгрузки", |
| | | 100 | | [new("3", "Доставка"), new("2", "Самовывоз"), new("60580", "Срочная доставка")], null, MinWidth: 220) |
| | | 101 | | ], |
| | | 102 | | model.AddressMappings.Select(m => Row(m.ShipmentWarehouseId, m.WarehouseName, |
| | | 103 | | ("BergShipmentAddressId", m.BergShipmentAddressId?.ToString(CultureInfo.InvariantCulture)), |
| | | 104 | | ("DispatchType", m.DispatchType.ToString(CultureInfo.InvariantCulture)))).ToList()); |
| | | 105 | | } |