| | | 1 | | using OzonDomains; |
| | | 2 | | using OzonDomains.Models; |
| | | 3 | | using Services.TransactionUtilsServices; |
| | | 4 | | |
| | | 5 | | namespace OzonOrdersWeb.WebServices.Transactions.Grid.Definitions; |
| | | 6 | | |
| | | 7 | | /// <summary>Участие 1С в проведении.</summary> |
| | | 8 | | public enum OneCMode |
| | | 9 | | { |
| | | 10 | | None, |
| | | 11 | | /// <summary>Пользователь решает флагом «Провести в 1С».</summary> |
| | | 12 | | Optional, |
| | | 13 | | Required |
| | | 14 | | } |
| | | 15 | | |
| | | 16 | | /// <summary>Какой документ 1С создаёт транзакция.</summary> |
| | | 17 | | public enum OneCDocumentKind |
| | | 18 | | { |
| | | 19 | | None, |
| | | 20 | | /// <summary>Перемещение запасов: склад-отправитель → склад-получатель (<c>TransferStockWithCustomWarehouses</c>).</ |
| | | 21 | | Transfer, |
| | | 22 | | /// <summary>Перемещение с «перевёрнутыми» складами по маппингу (<c>TransferStockByWarehousesWithReversedWarehouses< |
| | | 23 | | TransferReversed, |
| | | 24 | | /// <summary>Перемещение по складам заказов/засылу (<c>TransferStockByWarehouses</c>).</summary> |
| | | 25 | | TransferByWarehouses, |
| | | 26 | | /// <summary>Приходная накладная (<c>OneCReceiptManager.CreateReceipts</c>).</summary> |
| | | 27 | | Receipt, |
| | | 28 | | /// <summary>Расходная накладная (<c>OneCExpenseManager.SaleStockByWarehouses</c>).</summary> |
| | | 29 | | Expense |
| | | 30 | | } |
| | | 31 | | |
| | | 32 | | /// <summary>Откуда берутся склады для документа 1С.</summary> |
| | | 33 | | public enum WarehouseMode |
| | | 34 | | { |
| | | 35 | | None, |
| | | 36 | | /// <summary>Одна пара отправитель/получатель на весь документ (выбор в панели).</summary> |
| | | 37 | | GlobalPair, |
| | | 38 | | /// <summary>Только отправитель на документ (получатель — по маппингу).</summary> |
| | | 39 | | SenderOnly, |
| | | 40 | | /// <summary>Получатель у каждого заказа свой (CustomerReturn).</summary> |
| | | 41 | | PerOrderRecipient, |
| | | 42 | | /// <summary>И отправитель, и получатель у каждого заказа (ReturnToSupplier).</summary> |
| | | 43 | | PerOrderBoth, |
| | | 44 | | /// <summary>Склады по маппингу засыла/клиента без выбора пользователем.</summary> |
| | | 45 | | Mapping |
| | | 46 | | } |
| | | 47 | | |
| | | 48 | | /// <summary>Что делать с заказом, у которого количество уменьшили до нуля.</summary> |
| | | 49 | | public enum ZeroQuantityPolicy |
| | | 50 | | { |
| | | 51 | | None, |
| | | 52 | | /// <summary>Статус «К отмене» (заказ поставщику).</summary> |
| | | 53 | | ToCancellation, |
| | | 54 | | /// <summary>Статус «Утерян поставщиком» (приход от поставщика).</summary> |
| | | 55 | | LostBySupplier, |
| | | 56 | | /// <summary>Транзит «Утерян реализатором» через LostByCommissionerTransitHelper.</summary> |
| | | 57 | | LostByCommissioner |
| | | 58 | | } |
| | | 59 | | |
| | | 60 | | /// <summary> |
| | | 61 | | /// Декларативное описание транзакции для грида: статусы, интеграции, редактируемые поля и порядок шагов проведения. |
| | | 62 | | /// Дефолты имён/иконок переопределяются <see cref="TransactionTypeSetting"/> (см. <see cref="ITransactionDefinitionProv |
| | | 63 | | /// </summary> |
| | | 64 | | public sealed record TransactionDefinition |
| | | 65 | | { |
| | 263 | 66 | | public required TransactionType Type { get; init; } |
| | | 67 | | |
| | | 68 | | /// <summary>Сегмент URL: /Studio2/TransactionsGrid/{Slug}. kebab-case.</summary> |
| | 210 | 69 | | public required string Slug { get; init; } |
| | | 70 | | |
| | | 71 | | /// <summary>Код страницы прав (тот же, что у классической страницы) — роли не перенастраиваются.</summary> |
| | 76 | 72 | | public required string PageCode { get; init; } |
| | | 73 | | |
| | | 74 | | /// <summary>URL классической страницы — для прав на клиенте и fallback.</summary> |
| | 76 | 75 | | public required string LegacyEndpoint { get; init; } |
| | | 76 | | |
| | 169 | 77 | | public required string Title { get; init; } |
| | 45 | 78 | | public string? ShortName { get; init; } |
| | 105 | 79 | | public string Icon { get; init; } = "fas fa-circle"; |
| | 107 | 80 | | public string Color { get; init; } = "#6c757d"; |
| | 157 | 81 | | public required string Group { get; init; } |
| | 130 | 82 | | public int DisplayOrder { get; init; } |
| | 45 | 83 | | public string? Hint { get; init; } |
| | | 84 | | |
| | | 85 | | /// <summary>Целевой статус (fallback, если в StatusTransition нет строк). Пусто — статус не меняется.</summary> |
| | 30 | 86 | | public string? TargetStatusName { get; init; } |
| | | 87 | | |
| | | 88 | | /// <summary>Дополнительные статусы в выпадающем списке строки (например «Отменен», «К отмене»).</summary> |
| | 48 | 89 | | public IReadOnlyList<string> ExtraStatusNames { get; init; } = Array.Empty<string>(); |
| | | 90 | | |
| | | 91 | | /// <summary>Допустимые исходные статусы (fallback, если в StatusTransition нет строк). Пусто — любые.</summary> |
| | 57 | 92 | | public IReadOnlyList<string> AllowedSourceStatuses { get; init; } = Array.Empty<string>(); |
| | | 93 | | |
| | | 94 | | /// <summary>Статусы маркетплейса, при которых заказ нельзя провести (например «Отменен покупателем»).</summary> |
| | 46 | 95 | | public IReadOnlyList<string> DisallowMarketplaceStatuses { get; init; } = new[] { "Отменен покупателем" }; |
| | | 96 | | |
| | | 97 | | /// <summary>Заказы уже в этих статусах получают только смену статуса, без документа 1С.</summary> |
| | 45 | 98 | | public IReadOnlyList<string> StatusOnlyWhenAlreadyIn { get; init; } = Array.Empty<string>(); |
| | | 99 | | |
| | | 100 | | /// <summary>Использовать переходы из таблицы StatusTransition (иначе только дефолты выше).</summary> |
| | 49 | 101 | | public bool UseStatusTransitions { get; init; } = true; |
| | | 102 | | |
| | 74 | 103 | | public OneCMode OneCMode { get; init; } = OneCMode.None; |
| | 18 | 104 | | public OneCDocumentKind OneCDocument { get; init; } = OneCDocumentKind.None; |
| | 9 | 105 | | public WarehouseMode WarehouseMode { get; init; } = WarehouseMode.None; |
| | 3 | 106 | | public ZeroQuantityPolicy ZeroQuantityPolicy { get; init; } = ZeroQuantityPolicy.None; |
| | | 107 | | |
| | | 108 | | /// <summary>Проверять остатки 1С перед документом; дефицит — черновик.</summary> |
| | 2 | 109 | | public bool CheckStockBefore1C { get; init; } |
| | | 110 | | |
| | | 111 | | /// <summary>Уменьшение количества разбивает заказ на /1 и /2 (TransactOrder → SplitOrder).</summary> |
| | 1 | 112 | | public bool SupportsQuantitySplit { get; init; } |
| | | 113 | | |
| | | 114 | | /// <summary>Загружать C0 из WarehouseStock как подсказку к сохранённой цене закупки.</summary> |
| | 2 | 115 | | public bool ClearPurchasePriceOnLoad { get; init; } |
| | | 116 | | |
| | | 117 | | /// <summary>Цена закупки и поставщик обязательны (кроме статусов отмены и qty = 0).</summary> |
| | 2 | 118 | | public bool RequiresPurchasePrice { get; init; } |
| | | 119 | | |
| | | 120 | | /// <summary>При <see cref="RequiresPurchasePrice"/> обязателен только поставщик, цена закупки — нет.</summary> |
| | 1 | 121 | | public bool PurchasePriceOptional { get; init; } |
| | | 122 | | |
| | | 123 | | /// <summary>Подставлять C0 из WarehouseStock в пустую цену закупки при загрузке (с пересчётом, как ручной ввод).</s |
| | 1 | 124 | | public bool AutoFillPurchasePriceFromC0 { get; init; } |
| | | 125 | | |
| | | 126 | | /// <summary>Панель отмены отправления в Ozon у строк с клиентом OZON.</summary> |
| | 9 | 127 | | public bool OzonCancelPanel { get; init; } |
| | | 128 | | |
| | | 129 | | /// <summary> |
| | | 130 | | /// «Отменить в Ozon» включено по умолчанию с причиной 352 (как на классической «Отмене заказа», где панель всегда о |
| | | 131 | | /// иначе пользователь ставит галку сам. |
| | | 132 | | /// </summary> |
| | 18 | 133 | | public bool OzonCancelPreselected { get; init; } |
| | | 134 | | |
| | | 135 | | /// <summary>Группа колонок «Проведение» (отмена в Ozon и др.) развёрнута изначально, а не свёрнута до ярлыка.</summ |
| | 18 | 136 | | public bool ProcessingGroupOpen { get; init; } |
| | | 137 | | |
| | | 138 | | /// <summary>Флаг «Собрать отправление в Ozon» после проведения.</summary> |
| | 1 | 139 | | public bool ShipInOzon { get; init; } |
| | | 140 | | |
| | | 141 | | /// <summary>Показывать предложения API-поставщиков (раскрывающаяся строка).</summary> |
| | 3 | 142 | | public bool SupplierOffers { get; init; } |
| | | 143 | | |
| | | 144 | | /// <summary>Оформление в корзинах API-поставщиков.</summary> |
| | 15 | 145 | | public bool SupplierCarts { get; init; } |
| | | 146 | | |
| | | 147 | | /// <summary>Только правка цен, статус не меняется (Проценка).</summary> |
| | 22 | 148 | | public bool PriceEditingOnly { get; init; } |
| | | 149 | | |
| | | 150 | | /// <summary>Заказ должен иметь GUID операции 1С в комментарии прошлой транзакции.</summary> |
| | 1 | 151 | | public bool RequirePriorOneCGuid { get; init; } |
| | | 152 | | |
| | | 153 | | /// <summary>Заказы без остатка в WarehouseStock пропускаются.</summary> |
| | 1 | 154 | | public bool RequireWsStock { get; init; } |
| | | 155 | | |
| | | 156 | | /// <summary>Режим «из файла»: только смена статуса без 1С и выбора складов.</summary> |
| | 4 | 157 | | public bool SupportsBulkFromFile { get; init; } |
| | | 158 | | |
| | | 159 | | /// <summary>Параметры документа в панели: договор/НДС/номер и дата входящего.</summary> |
| | 1 | 160 | | public bool ReceiptDocumentFields { get; init; } |
| | | 161 | | |
| | | 162 | | /// <summary>Параметры расходной: договор клиента/НДС/комментарий/дата операции.</summary> |
| | 2 | 163 | | public bool ExpenseDocumentFields { get; init; } |
| | | 164 | | |
| | | 165 | | /// <summary>Страна происхождения и ГТД по строкам (приходная накладная).</summary> |
| | 1 | 166 | | public bool CountryAndGtdFields { get; init; } |
| | | 167 | | |
| | | 168 | | /// <summary>Заказы должны быть от одного поставщика (по ИНН) и с одного эффективного склада.</summary> |
| | 1 | 169 | | public bool RequireSingleSupplierAndWarehouse { get; init; } |
| | | 170 | | |
| | | 171 | | /// <summary>Редактируемые поля строки (camelCase имена колонок грида).</summary> |
| | 221 | 172 | | public IReadOnlyList<string> EditableFields { get; init; } = Array.Empty<string>(); |
| | | 173 | | |
| | | 174 | | /// <summary>Ключи шагов проведения по порядку (см. TransactionCommitStepKeys).</summary> |
| | 177 | 175 | | public required IReadOnlyList<string> Steps { get; init; } |
| | | 176 | | |
| | | 177 | | /// <summary>Создание записи Transaction — делегат TransactionManager.</summary> |
| | 44 | 178 | | public required Func<TransactionManager, List<Order>, string, DateTime, string, Task<(int, string, int)>> CreateTran |
| | | 179 | | |
| | | 180 | | /// <summary> |
| | | 181 | | /// Кнопки OrdersGrid ведут на грид. По умолчанию включено для всех типов: с /Studio2/OrdersGrid — новый грид, |
| | | 182 | | /// с классического списка заказов — классические страницы. Админка может выключить тип (откат на старую страницу и |
| | | 183 | | /// </summary> |
| | 73 | 184 | | public bool UseGrid { get; init; } = true; |
| | | 185 | | |
| | | 186 | | /// <summary>Выключенный тип не показывается в меню проведения (из <see cref="TransactionTypeSetting.IsEnabled"/>).< |
| | 66 | 187 | | public bool IsEnabled { get; init; } = true; |
| | | 188 | | |
| | | 189 | | /// <summary>Пользовательские дефолты страницы (JSON из админки), как есть отдаётся клиенту.</summary> |
| | 6 | 190 | | public string? DefaultsJson { get; init; } |
| | | 191 | | |
| | 16 | 192 | | public string GridEndpoint => $"/Studio2/TransactionsGrid/{Slug}"; |
| | | 193 | | } |