@startuml actor Пользователь participant "АРМ" as UI participant "Gateway" as GW participant "Scrooge\n(список причин)" as SCR participant "Backend" as BE participant "WorkFlow\nimportPriceSupplyToOrderWorkflow" as WF participant "MongoDB" as ORD participant "Product‑info\n(SKU в GUID)" as PI participant "Scrooge\n(лимиты и скидки)" as LIM participant "MS Product\n(названия товаров)" as PRD autonumber == Получение списка причин == Пользователь -> UI : нажимает «Импорт цен» UI -> GW : GET /info/v1/discount-manual-types GW -> SCR : вызов ручки получения типов SCR --> GW : ответ 200 (список причин) GW --> UI : ответ 200 (список причин) UI -> UI : отображает список причин для выбора Пользователь -> UI : выбирает причину == Загрузка Excel‑файла == Пользователь -> UI : прикрепляет Excel и нажимает «Загрузить» UI -> GW : POST /orders/v1/{orderId}/products/import-price\n(file + manualType) GW -> BE : перенаправляет запрос == Парсинг Excel == BE -> BE : • парсинг\n• нормализация\n• базовая валидация alt обнаружены бизнес‑ошибки при парсинге BE -> BE : формирует ошибки\n(price_null, duplicate) BE -> GW : ответ 200 + ошибки GW -> UI : ответ 200 + ошибки UI -> Пользователь : показывает список ошибок\nбизнес-ошибка "Товар не найден..." end BE -> WF : запускает WorkFlow (orderId, manualType, [{GUID/SKU, price}]) == WF — проверка товара == WF -> ORD : товар по GUID есть? alt товар не найден ORD --> WF : Ответ, что товар найден WF -> PI : вызывает ConvertSkusToUids(SKU)\nhigh+low → GUID PI --> WF : отдает GUID WF -> ORD : повторная проверка по GUID ORD --> WF : найден / нет alt всё ещё не найден WF -> WF : пропускает товар end end == WF — проверка статусов == WF -> ORD : запрос статуса товара / заказа ORD -> WF: ответ со статусом товара / заказа alt статус недопустим WF -> BE : бизнес‑ошибка «Корректировка недоступна…» end == WF — проверка цен == WF -> LIM : получает скидки по товарам LIM --> WF : возможные скидки WF -> WF : сравнивает цену из файла с минимальной доступной alt цена ниже доступной WF -> WF : устанавливает минимальную цену по правам WF -> BE : бизнес‑ошибка «Цена ниже допустимой…» end == WF — обновление заказа == WF -> ORD : обновляет кучу полей с ценами и скидками\nлогирует корректировку цен ORD --> WF : отдает результат выполнения скрипта == Завершение == WF -> PRD : Отдает GUID товара PRD --> WF : Получает SKU + Name товара WF --> BE : отдает результат и ошибки BE --> GW : ответ 200 + ошибки (если есть) GW --> UI : ответ 200 + ошибки (если есть) UI --> Пользователь : показывает ошибки (если есть)\nи обновленные цены @enduml