refine scheme implementation
This commit is contained in:
121
oms/interface-arm/docs/vat_change_invoice.puml
Normal file
121
oms/interface-arm/docs/vat_change_invoice.puml
Normal file
@@ -0,0 +1,121 @@
|
||||
@startuml Редактирование счета на оплату
|
||||
!pragma teoz true
|
||||
|
||||
title AS IS Редактирование счета на оплату (флоу из ТЗ COMPRO-3467)
|
||||
|
||||
actor "Пользователь (АРМ)" as User
|
||||
participant "Frontend (АРМ)" as Front
|
||||
participant "Gateway (Прокси)" as Gateway
|
||||
participant "OMS-Documents (метаданные)" as Docs
|
||||
participant "Хранилище (S3)" as S3
|
||||
participant "OMS-Print (конвертация)" as Print
|
||||
participant "Редактор (Tiptap)" as Editor
|
||||
|
||||
== 1. ИНИЦИАЦИЯ РЕДАКТИРОВАНИЯ (ПОЛУЧЕНИЕ HTML) ==
|
||||
|
||||
User -> Front: Клик "Редактировать счет" (актуальный)
|
||||
activate Front
|
||||
|
||||
Front -> Gateway: GET /documents/v1/invoice/{id}/html
|
||||
activate Gateway
|
||||
|
||||
Gateway -> Docs: Запрос docURL для invoiceID
|
||||
activate Docs
|
||||
Docs --> Gateway: docURL (ссылка на PDF в S3)
|
||||
deactivate Docs
|
||||
|
||||
Gateway -> S3: Запрос PDF файла по docURL
|
||||
activate S3
|
||||
S3 --> Gateway: PDF файл счета
|
||||
deactivate S3
|
||||
|
||||
Gateway -> Print: Конвертация PDF в HTML (вызов метода)
|
||||
activate Print
|
||||
Print --> Gateway: HTML файл счета
|
||||
deactivate Print
|
||||
|
||||
Gateway --> Front: HTML файл (ответ 200)
|
||||
deactivate Gateway
|
||||
|
||||
Front -> Editor: Инициализация редактора с HTML
|
||||
activate Editor
|
||||
Editor --> Front: Готово
|
||||
deactivate Editor
|
||||
|
||||
Front --> User: Открыто окно редактора
|
||||
deactivate Front
|
||||
|
||||
== 2. РЕДАКТИРОВАНИЕ И СОХРАНЕНИЕ НОВОЙ ВЕРСИИ ==
|
||||
|
||||
User -> Editor: Вносит изменения (текст, таблицы)
|
||||
activate Editor
|
||||
Editor --> User: Изменения отображены
|
||||
User -> Editor: Клик "Сохранить"
|
||||
Editor -> Front: Передача измененного HTML
|
||||
deactivate Editor
|
||||
activate Front
|
||||
|
||||
Front -> Gateway: POST /documents/v1/invoice/{id}/html\n{ "html": "..." }
|
||||
activate Gateway
|
||||
|
||||
Gateway -> Print: Конвертация HTML в PDF
|
||||
activate Print
|
||||
Print --> Gateway: Новый PDF файл
|
||||
deactivate Print
|
||||
|
||||
Gateway -> S3: Сохранение нового PDF файла
|
||||
activate S3
|
||||
S3 --> Gateway: newDocURL (ссылка на новый файл)
|
||||
deactivate S3
|
||||
|
||||
Gateway -> Docs: Создание новой версии записи\n(новый docURL, isSend:false, обновленные Base/Details)
|
||||
activate Docs
|
||||
Docs --> Gateway: OK (новая версия создана)
|
||||
deactivate Docs
|
||||
|
||||
Gateway --> Front: 204 No Content (Успех)
|
||||
deactivate Gateway
|
||||
|
||||
== 3. ОБНОВЛЕНИЕ ИНТЕРФЕЙСА ==
|
||||
|
||||
Front -> User: 1. Закрывает редактор\n2. Уведомление "Счет изменен"
|
||||
Front -> Gateway: Вызов getInvoiceLatest (перезапрос)
|
||||
activate Gateway
|
||||
Gateway -> Docs: Запрос последней версии счета
|
||||
activate Docs
|
||||
Docs --> Gateway: Данные обновленного счета (с newDocURL)
|
||||
deactivate Docs
|
||||
Gateway --> Front: Данные обновленного счета
|
||||
deactivate Gateway
|
||||
|
||||
Front -> User: Обновляет отображение во вкладке "Счет на оплату"
|
||||
deactivate Front
|
||||
|
||||
@enduml
|
||||
|
||||
@startuml
|
||||
|
||||
@enduml
|
||||
|
||||
|
||||
|
||||
@startuml
|
||||
|
||||
title TO BE Логика расчета НДС
|
||||
|
||||
actor "Триггер" as User
|
||||
participant "OMS" as OMS
|
||||
participant "NDS" as NDS
|
||||
|
||||
User -> OMS: Создание спеки / счета на оплату / триггер ПМП
|
||||
OMS --> OMS: Заполнение необходимых данных (Блок КА, блок доставок,\nшапка документа и т.д. в зависимости от типа документа)
|
||||
OMS -> NDS: Вызывает метод: nds/vat_calc в сервисе NDS
|
||||
alt Если вернулся nds_calc = nds_reverse || nds_calc = nds_direct
|
||||
OMS -> NDS: Запрашашивает НДС и производные
|
||||
NDS --> OMS: answer
|
||||
OMS --> OMS: Подставляет НДС и производные из ответа сервиса NDS
|
||||
else Если вернулся nds_calc = self
|
||||
OMS --> OMS: Рассчитывает НДС и производные по формуле (UnitPrice*20)/120\n(как и было)
|
||||
end
|
||||
OMS --> User: answer
|
||||
@enduml
|
||||
45
oms/pmp/new_vat_for_punchout.puml
Normal file
45
oms/pmp/new_vat_for_punchout.puml
Normal file
@@ -0,0 +1,45 @@
|
||||
@startuml
|
||||
|
||||
group Флоу НДС в punchout (До реализации интеграции с сервисом NDS в Q1 26)
|
||||
|
||||
OMS-> Адаптер: В топик partner.order.confirm передает цену из Order
|
||||
Адаптер -> Адаптер: Проверяет flow_id
|
||||
Адаптер -> Адаптер: Компилирует сообщение для punchout
|
||||
Адаптер -> WTIS: Вызывает метод: /api/order/verification/<order_guid>
|
||||
WTIS --> Адаптер: answer
|
||||
alt Если вернулся check_sale_docs == true
|
||||
Адаптер -> NDS: Запрашивает НДС и производные
|
||||
NDS --> Адаптер: answer
|
||||
Адаптер --> Адаптер: Подставляет НДС и производные из ответа сервиса NDS
|
||||
else Если вернулся check_sale_docs == false
|
||||
Адаптер --> Адаптер: Рассчитывает НДС и производные по формуле (UnitPrice*20)/120\n(как и было)
|
||||
end
|
||||
Адаптер -> Punchout: Отправка заказа
|
||||
|
||||
end
|
||||
@enduml
|
||||
|
||||
|
||||
|
||||
@startuml
|
||||
|
||||
title Флоу НДС в punchout (После реализации интеграции с сервисом NDS в Q1 26)
|
||||
|
||||
actor "Триггер" as User
|
||||
participant "OMS" as OMS
|
||||
participant "WTIS" as WTIS
|
||||
participant "NDS" as NDS
|
||||
|
||||
User -> OMS: Создание спеки / счета на оплату / триггер ПМП
|
||||
OMS --> OMS: Заполнение необходимых данных (Блок КА, блок доставок,\nшапка документа и т.д. в зависимости от типа документа)
|
||||
OMS -> WTIS: Вызывает метод: /api/order/verification/<order_guid>
|
||||
WTIS --> OMS: answer
|
||||
alt Если вернулся check_sale_docs == true
|
||||
OMS -> NDS: Запрашивает НДС и производные
|
||||
NDS --> OMS: answer
|
||||
OMS --> OMS: Подставляет НДС и производные из ответа сервиса NDS
|
||||
else Если вернулся check_sale_docs == false
|
||||
OMS --> OMS: Рассчитывает НДС и производные по формуле (UnitPrice*20)/120\n(как и было)
|
||||
end
|
||||
OMS --> User: answer
|
||||
@enduml
|
||||
412
oms/process/correction-new.puml
Normal file
412
oms/process/correction-new.puml
Normal file
@@ -0,0 +1,412 @@
|
||||
@startuml Order Edit Process
|
||||
skinparam backgroundColor #FFFFFF
|
||||
skinparam componentStyle rectangle
|
||||
|
||||
title Бизнес-процесс редактирования заказа
|
||||
|
||||
actor User as U
|
||||
participant "Frontend ARM" as F
|
||||
participant "Gateway" as G
|
||||
participant "Workflow" as W
|
||||
participant "Order" as OS
|
||||
participant "History" as H
|
||||
participant "WTIS" as WTIS
|
||||
participant "MongoDB" as DB
|
||||
|
||||
== Инициация редактирования ==
|
||||
|
||||
U -> F: Клик на кнопку "Редактирование заказа"
|
||||
activate F
|
||||
|
||||
F -> G: GET /orders/v1/{orderID}/start-correction
|
||||
activate G
|
||||
|
||||
G -> W: Запускает workflow B2CGetEditableFieldsWorkflow
|
||||
activate W
|
||||
|
||||
== Workflow: Получение редактируемых полей ==
|
||||
|
||||
W -> OS: gRPC: GetOrder(orderID)
|
||||
activate OS
|
||||
OS -> DB: Поиск заказа
|
||||
DB --> OS: Данные заказа
|
||||
OS --> W: Order entity
|
||||
deactivate OS
|
||||
|
||||
W -> H: gRPC: IsTransactionExist(orderID)
|
||||
activate H
|
||||
H -> H: Transaction Service\nIsTransactionExist()
|
||||
H -> DB: Поиск открытой транзакции
|
||||
DB --> H: TransactionID или null
|
||||
H --> W: TransactionID или uuid.Nil
|
||||
deactivate H
|
||||
|
||||
alt Транзакция не существует
|
||||
W -> H: gRPC: StartTransaction(orderID, userID)
|
||||
activate H
|
||||
H -> H: Transaction Service\nStartTransaction()
|
||||
H -> H: Создание новой транзакции\n(статус: Opened)
|
||||
H -> DB: Сохранение транзакции
|
||||
DB --> H: Подтверждение
|
||||
H --> W: TransactionID
|
||||
deactivate H
|
||||
end
|
||||
|
||||
W -> W: Определение редактируемых полей
|
||||
W -> WTIS: API GET GetEditableFieldsFromWTIS(orderID)
|
||||
activate WTIS
|
||||
WTIS --> W: Права на редактирование атрибутов
|
||||
deactivate WTIS
|
||||
|
||||
W -> W: Проверка прав пользователя\n(permissions)
|
||||
W -> W: Формирование ответа\n(CorrectionAnswer)
|
||||
W --> G: Результат workflow
|
||||
deactivate W
|
||||
|
||||
G --> F: CorrectionAnswer\n(редактируемые поля)
|
||||
deactivate G
|
||||
|
||||
F -> F: Показать уведомление\n"У вас есть 5 минут на редактирование"
|
||||
F --> U: Интерфейс редактирования активирован
|
||||
deactivate F
|
||||
|
||||
== Мониторинг транзакции ==
|
||||
|
||||
loop Каждые 30 секунд
|
||||
F -> F: checkOrderHasTransaction()
|
||||
F -> G: GET /orders/v1/{orderID}
|
||||
G --> F: hasTransaction: boolean
|
||||
alt hasTransaction = false
|
||||
F -> F: Показать ошибку\n"Время на редактирование вышло"
|
||||
F -> F: Перезагрузить страницу
|
||||
end
|
||||
end
|
||||
== Завершение редактирования ==
|
||||
|
||||
U -> F: Клик "Сохранить" или "Отменить"
|
||||
activate F
|
||||
|
||||
F -> G: GET /orders/v1/{orderID}/end-correction\n?typeCorrection=...&typeEndCorrection=...
|
||||
activate G
|
||||
|
||||
G -> W: запускает workflow B2CEndCorrectionsWorkflow
|
||||
activate W
|
||||
|
||||
== Workflow: Завершение редактирования ==
|
||||
|
||||
W -> W: Lock ресурса (mutex)\n(10 минут блокировка)
|
||||
|
||||
W -> OS: gRPC: GetOrder(orderID)
|
||||
activate OS
|
||||
OS -> DB: Поиск заказа
|
||||
DB --> OS: Данные заказа
|
||||
OS --> W: Order entity
|
||||
deactivate OS
|
||||
|
||||
W -> H: gRPC: IsTransactionExist(orderID)
|
||||
activate H
|
||||
H -> H: Transaction Service\nIsTransactionExist()
|
||||
H -> DB: Поиск транзакции
|
||||
DB --> H: TransactionID
|
||||
H --> W: TransactionID
|
||||
deactivate H
|
||||
|
||||
alt typeEndCorrection = "reject"
|
||||
W -> H: gRPC: EndTransaction(orderID, userID, true)
|
||||
activate H
|
||||
H -> H: Закрытие транзакции\n(статус: Rejected)
|
||||
H -> DB: Обновление транзакции
|
||||
DB --> H: Подтверждение
|
||||
H --> W: Результат
|
||||
deactivate H
|
||||
W -> W: Unlock ресурса
|
||||
W --> G: Успешная отмена
|
||||
G --> F: Результат завершения транзакции
|
||||
F -> F: Обновление интерфейса
|
||||
F --> U: Редактирование завершено
|
||||
deactivate F
|
||||
else typeEndCorrection = "success"
|
||||
W -> W: Старт ручного действия коррекции
|
||||
W -> W: Подготовка заказа и шипментов\nконвертация в OrderToWtis
|
||||
|
||||
W -> WTIS: API POST /api/v1/oms_sync\nСинхронизация заказа с WTIS
|
||||
activate WTIS
|
||||
WTIS -> WTIS: Обработка изменений\n(валидация, расчёты, статусы и т.п.)
|
||||
WTIS --> W: OrderSyncResponse\n(подтверждение или бизнес‑ошибки)
|
||||
deactivate WTIS
|
||||
W -> W: Проверка ответа (бизнес-ошибки или модель заказа)
|
||||
|
||||
alt бизнес-ошибка от WTIS
|
||||
W --> G: Ошибка сохранения
|
||||
|
||||
|
||||
G --> F: Отображение ошибки\nЗавершения транзакции
|
||||
deactivate G
|
||||
|
||||
F -> F: Обновление интерфейса с ошибкой
|
||||
F --> U: Редактирование не завершено
|
||||
deactivate F
|
||||
end
|
||||
W -> W: Преобразование ответа WTIS в модель заказа OMS
|
||||
|
||||
W -> H: gRPC: EndTransaction(orderID, userID, false)
|
||||
activate H
|
||||
H -> H: Transaction Service\nEndTransaction()
|
||||
H -> H: Закрытие транзакции\n(статус: Finished)
|
||||
H -> DB: Обновление транзакции
|
||||
DB --> H: answer
|
||||
H -> H: publishEvents()\n(публикация событий)
|
||||
H --> W: Результат
|
||||
deactivate H
|
||||
|
||||
W -> W: Сохранение изменений
|
||||
W -> OS: gRPC: UpsertOrderWithShipment(orderID)
|
||||
activate OS
|
||||
OS -> H: Transaction Service\nIsTransactionExist()
|
||||
activate H
|
||||
H -> DB: Поиск транзакции
|
||||
DB --> H: TransactionID
|
||||
H --> OS: TransactionID
|
||||
deactivate H
|
||||
OS -> DB: Сохранение заказа
|
||||
DB --> OS: Подтверждение
|
||||
OS --> W: Order entity
|
||||
deactivate OS
|
||||
|
||||
W -> W: Unlock ресурса
|
||||
W --> G: Успешное сохранение
|
||||
deactivate W
|
||||
|
||||
G --> F: Результат завершения транзакции
|
||||
deactivate G
|
||||
|
||||
F -> F: Обновление интерфейса
|
||||
F --> U: Редактирование завершено
|
||||
deactivate F
|
||||
end
|
||||
|
||||
|
||||
@enduml
|
||||
|
||||
|
||||
|
||||
|
||||
@startuml EditOrder
|
||||
skinparam backgroundColor #FFFFFF
|
||||
skinparam componentStyle rectangle
|
||||
|
||||
title Бизнес-процесс редактирования заказа
|
||||
|
||||
actor User as U
|
||||
participant "Frontend ARM" as F
|
||||
participant "Gateway" as G
|
||||
participant "Workflow" as W
|
||||
participant "Order" as OS
|
||||
participant "History" as H
|
||||
participant "WTIS" as WTIS
|
||||
participant "MongoDB" as DB
|
||||
|
||||
== Инициация редактирования ==
|
||||
|
||||
U -> F: Клик на кнопку "Редактирование заказа"
|
||||
activate F
|
||||
|
||||
F -> G: GET /orders/v1/{orderID}/start-correction
|
||||
activate G
|
||||
|
||||
G -> W: Запускает workflow B2CGetEditableFieldsWorkflow
|
||||
activate W
|
||||
|
||||
'==============================================================================
|
||||
== Workflow: Получение редактируемых полей ==
|
||||
'==============================================================================
|
||||
|
||||
W -> OS: gRPC: GetOrder(orderID)
|
||||
activate OS
|
||||
OS -> DB: Поиск заказа
|
||||
DB --> OS: Данные заказа
|
||||
OS --> W: Order entity
|
||||
deactivate OS
|
||||
|
||||
W -> H: gRPC: IsTransactionExist(orderID)
|
||||
activate H
|
||||
H -> H: Transaction Service\nIsTransactionExist()
|
||||
H -> DB: Поиск открытой транзакции
|
||||
DB --> H: TransactionID или null
|
||||
H --> W: TransactionID или uuid.Nil
|
||||
deactivate H
|
||||
|
||||
alt Транзакция не существует
|
||||
W -> H: gRPC: StartTransaction(orderID, userID)
|
||||
activate H
|
||||
H -> H: Transaction Service\nStartTransaction()
|
||||
H -> H: Создание новой транзакции\n(статус: Opened)
|
||||
H -> DB: Сохранение транзакции
|
||||
DB --> H: Подтверждение
|
||||
H --> W: TransactionID
|
||||
deactivate H
|
||||
end
|
||||
|
||||
W -> W: Определение редактируемых полей
|
||||
W -> WTIS: API GET GetEditableFieldsFromWTIS(orderID)
|
||||
activate WTIS
|
||||
WTIS --> W: Права на редактирование атрибутов
|
||||
deactivate WTIS
|
||||
|
||||
W -> W: Проверка прав пользователя\n(permissions)
|
||||
W -> W: Формирование ответа\n(CorrectionAnswer)
|
||||
W --> G: Результат workflow
|
||||
deactivate W
|
||||
|
||||
G --> F: CorrectionAnswer\n(редактируемые поля)
|
||||
deactivate G
|
||||
|
||||
F -> F: Показать уведомление\n"У вас есть 5 минут на редактирование"
|
||||
F --> U: Интерфейс редактирования активирован
|
||||
deactivate F
|
||||
|
||||
'==============================================================================
|
||||
== Мониторинг транзакции ==
|
||||
'==============================================================================
|
||||
|
||||
loop Каждые 30 секунд
|
||||
F -> F: checkOrderHasTransaction()
|
||||
F -> G: GET /orders/v1/{orderID}
|
||||
G --> F: hasTransaction: boolean
|
||||
alt hasTransaction = false
|
||||
F -> F: Показать ошибку\n"Время на редактирование вышло"
|
||||
F -> F: Перезагрузить страницу
|
||||
end
|
||||
end
|
||||
|
||||
'==============================================================================
|
||||
== Завершение редактирования ==
|
||||
'==============================================================================
|
||||
|
||||
U -> F: Клик "Сохранить" или "Отменить"
|
||||
activate F
|
||||
|
||||
F -> G: GET /orders/v1/{orderID}/end-correction\n?typeCorrection=...&typeEndCorrection=...
|
||||
activate G
|
||||
|
||||
G -> W: запускает workflow B2CEndCorrectionsWorkflow
|
||||
activate W
|
||||
|
||||
'==============================================================================
|
||||
== Workflow: Завершение редактирования ==
|
||||
'==============================================================================
|
||||
|
||||
W -> W: Lock ресурса (mutex)\n(10 минут блокировка)
|
||||
|
||||
W -> OS: gRPC: GetOrder(orderID)
|
||||
activate OS
|
||||
OS -> DB: Поиск заказа
|
||||
DB --> OS: Данные заказа
|
||||
OS --> W: Order entity
|
||||
deactivate OS
|
||||
|
||||
W -> H: gRPC: GetTransactionByOrder(orderID)\n(получение транзакции)
|
||||
activate H
|
||||
H -> DB: Поиск транзакции
|
||||
DB --> H: answer
|
||||
H --> W: answer
|
||||
deactivate H
|
||||
|
||||
alt typeEndCorrection = "reject"
|
||||
W -> H: gRPC: EndTransaction(orderID, userID, true)
|
||||
activate H
|
||||
H -> DB: Обновление статуса транзакции\n(статус: Rejected)
|
||||
DB --> H: Подтверждение
|
||||
H --> W: answer
|
||||
deactivate H
|
||||
|
||||
W -> W: Unlock ресурса
|
||||
W --> G: Успешная отмена
|
||||
G --> F: Результат завершения транзакции
|
||||
F -> F: Обновление интерфейса
|
||||
F --> U: Редактирование завершено
|
||||
deactivate F
|
||||
else typeEndCorrection = "success"
|
||||
W -> W: Старт workflow ManualActionWorkflow
|
||||
|
||||
W -> WTIS: API POST /api/order/oms_sync\n(через ActionsB2CManualWorkflow)
|
||||
activate WTIS
|
||||
WTIS -> WTIS: Обработка изменений
|
||||
WTIS --> W: OrderSyncResponse\n(подтверждение или бизнес‑ошибки)
|
||||
deactivate WTIS
|
||||
|
||||
alt бизнес-ошибка / ошибка синхронизации
|
||||
W -> W: Формирование ManualActionRes.BusinessError
|
||||
W -> W: Unlock ресурса
|
||||
W --> G: Ошибка завершения коррекции\n(B2CEndCorrectionsWorkflow возвращает res.Error)
|
||||
|
||||
G --> F: Отображение ошибки\nзавершения транзакции
|
||||
deactivate G
|
||||
|
||||
F -> F: Обновление интерфейса с ошибкой
|
||||
F --> U: Отображение в интерфейсе ошибки\n"Редактирование не завершено"
|
||||
deactivate F
|
||||
else успешный ответ WTIS
|
||||
W -> W: Преобразование ответа WTIS\nв модель заказа OMS
|
||||
W -> OS: Запись (orderFromWTIS) в БД, шипменты, события
|
||||
activate OS
|
||||
OS --> W: asnwer
|
||||
deactivate OS
|
||||
|
||||
W -> OS: gRPC: GetOrder(orderID)\n(повторное чтение обновлённого заказа)
|
||||
activate OS
|
||||
OS -> DB: Поиск заказа (включая shipment)
|
||||
activate DB
|
||||
DB --> OS: Обновлённые данные заказа
|
||||
deactivate DB
|
||||
OS --> W: Order entity
|
||||
deactivate OS
|
||||
|
||||
alt B2B Заказ
|
||||
W -> H: gRPC: GetEventsByDraft(draft)
|
||||
activate H
|
||||
H -> DB: Поиск событий по транзакции
|
||||
DB --> H: Events
|
||||
H --> W: Events
|
||||
deactivate H
|
||||
|
||||
W -> H: gRPC: IsNeedInvoiceGenerate(events)
|
||||
activate H
|
||||
H -> H: Анализ событий\nнужна ли перегенерация счёта
|
||||
H --> W: IsNeedInvoiceGenerate
|
||||
deactivate H
|
||||
|
||||
W -> W: Определение менялась ли закупочная цена
|
||||
|
||||
alt IsNeedInvoiceGenerate == true
|
||||
W -> W: Вызов дочернего WF перегенерации счета\n(InvoiceGenerateWorkflow)
|
||||
W <- W: Результат генерации счёта\n(ошибка или успех).\nПри ошибке - возврат ошибки пользователю
|
||||
end
|
||||
end
|
||||
|
||||
W -> H: gRPC: EndTransaction(orderID, userID, false)
|
||||
activate H
|
||||
H -> H: Transaction Service\nEndTransaction()
|
||||
H -> DB: Обновление транзакции\n(статус: Finished)
|
||||
DB --> H: Подтверждение
|
||||
H -> Kafka: публикация в топик oms.order.before_publish.<stage>
|
||||
activate Kafka
|
||||
Kafka --> H: Подтверждение публикации
|
||||
deactivate Kafka
|
||||
H --> W: Результат
|
||||
deactivate H
|
||||
|
||||
W -> W: Unlock ресурса
|
||||
W --> G: Успешное завершение коррекции
|
||||
deactivate W
|
||||
|
||||
G --> F: Результат завершения транзакции
|
||||
deactivate G
|
||||
|
||||
F -> F: Обновление интерфейса
|
||||
F --> U: Редактирование завершено
|
||||
deactivate F
|
||||
end
|
||||
end
|
||||
|
||||
@enduml
|
||||
259
oms/t-shop/er-diagram.puml
Normal file
259
oms/t-shop/er-diagram.puml
Normal file
@@ -0,0 +1,259 @@
|
||||
@startuml
|
||||
hide circle
|
||||
skinparam linetype ortho
|
||||
left to right direction
|
||||
|
||||
entity "order" as order {
|
||||
id : bigint <<PK>> <<NN>> autoincrement
|
||||
// Идентификатор записи
|
||||
--
|
||||
t_shop_order_id : bigint <<NN>>
|
||||
// Идентификатор заказа в T-Shop
|
||||
|
||||
created_at : timestamptz <<NN>>
|
||||
// Дата и время оформления заказа в формате ISO 8601 UTC
|
||||
|
||||
delivery_total : numeric(10,2)
|
||||
// Стоимость доставки
|
||||
|
||||
expiry_date : timestamptz
|
||||
// Дата отмены заказа при бездействии (ISO 8601 UTC)
|
||||
|
||||
items_total : numeric(10,2)
|
||||
// Платеж покупателя
|
||||
|
||||
comment : varchar(256)
|
||||
// Комментарий к заказу
|
||||
|
||||
status : enum('CANCELLED','PROCESSING','DELIVERY','PICKUP','DELIVERED') <<NN>>
|
||||
// Статус заказа
|
||||
|
||||
substatus : enum('STARTED','READY_TO_SHIP','SHOP_FAILED','USER_CHANGED_MIND')
|
||||
// Этап обработки заказа
|
||||
|
||||
updated_at : timestamptz <<NN>>
|
||||
// Дата и время последнего обновления заказа в формате ISO 8601 с указанием смещения относительно UTC.
|
||||
}
|
||||
|
||||
entity "sync_log" as sync_log {
|
||||
id : bigint <<PK>> <<NN>> autoincrement
|
||||
// Идентификатор записи
|
||||
--
|
||||
last_synced_updated_at : timestamptz <<NN>>
|
||||
// Время последней синхронизации
|
||||
|
||||
retry_policy_attempts : smallint
|
||||
// Количество попыток retry policy
|
||||
|
||||
last_error : json
|
||||
// JSON запроса и ответа при котором произошла ошибка
|
||||
|
||||
current_page_token : varchar(100)
|
||||
// Идентификатор следующей страницы результатов
|
||||
|
||||
status : enum('success','error') <<NN>>
|
||||
// Статус синхронизации (success, error)
|
||||
}
|
||||
|
||||
entity "order_status_history" as order_status_history {
|
||||
id : bigint <<PK>> <<NN>> autoincrement
|
||||
// Идентификатор записи
|
||||
--
|
||||
order_id : bigint <<NN>>
|
||||
// Идентификатор заказа
|
||||
|
||||
status : enum('CANCELLED','PROCESSING','DELIVERY','PICKUP','DELIVERED') <<NN>>
|
||||
// Статус заказа
|
||||
|
||||
substatus : enum('STARTED','READY_TO_SHIP','SHOP_FAILED','USER_CHANGED_MIND')
|
||||
// Этап обработки заказа
|
||||
|
||||
created_at : timestamptz <<NN>>
|
||||
// Время создания записи
|
||||
}
|
||||
|
||||
entity "outlet" as outlet {
|
||||
id : bigint <<PK>> <<NN>> autoincrement
|
||||
// Идентификатор записи
|
||||
--
|
||||
outlet_code : uuid
|
||||
// Идентификатор пункта самовывоза
|
||||
|
||||
outlet_name : varchar(100)
|
||||
// Наименование пункта самовывоза
|
||||
===
|
||||
// В последствии добавим и другие атрибуты если нужно будет синкать ПВЗ. На данный момент этот функционал в фидах
|
||||
}
|
||||
|
||||
entity "order_buyer" as buyer {
|
||||
id : bigint <<PK>> <<NN>> autoincrement
|
||||
// Идентификатор записи
|
||||
--
|
||||
t_shop_order_id : bigint
|
||||
// Идентификатор заказа тиньков
|
||||
|
||||
phone : varchar(20) <<NN>>
|
||||
// Номер телефона покупателя
|
||||
|
||||
email : varchar(255) <<NN>>
|
||||
// Почта для отправки чека
|
||||
|
||||
first_name : varchar(100) <<NN>>
|
||||
// Имя покупателя
|
||||
|
||||
last_name : varchar(100) <<NN>>
|
||||
// Фамилия покупателя
|
||||
}
|
||||
|
||||
entity "order_delivery" as delivery {
|
||||
id : bigint <<PK>> <<NN>> autoincrement
|
||||
// Идентификатор записи
|
||||
--
|
||||
t_shop_order_id : bigint
|
||||
// Идентификатор заказа тиньков
|
||||
|
||||
lift_price : numeric(10,2)
|
||||
// Стоимость подъема на этаж (руб)
|
||||
|
||||
lift_type : order_lift_type
|
||||
// Тип подъема: NOT_NEEDED, MANUAL, ELEVATOR, CARGO_ELEVATOR, FREE, UNKNOWN
|
||||
|
||||
outlet_code : varchar(100)
|
||||
// Идентификатор пункта самовывоза магазина
|
||||
|
||||
outlet_storage_limit_date : timestamptz
|
||||
// Дата хранения в пункте выдачи (только для статуса PICKUP)
|
||||
|
||||
service_name : varchar(255)
|
||||
// Наименование службы доставки
|
||||
|
||||
type : order_delivery_type
|
||||
// Способ доставки: DELIVERY, PICKUP, UNKNOWN
|
||||
|
||||
real_delivery_date : timestamptz
|
||||
// Фактическая дата доставки (ISO 8601 UTC)
|
||||
}
|
||||
|
||||
entity "order_delivery_address" as address {
|
||||
id : bigint <<PK>> <<NN>> autoincrement
|
||||
// Идентификатор записи
|
||||
--
|
||||
t_shop_order_id : bigint
|
||||
// Идентификатор заказа тиньков
|
||||
|
||||
full_address : text <<NN>>
|
||||
// Полный адрес доставки (очень полный, до уровня квартиры если есть)
|
||||
|
||||
apartment : varchar(20)
|
||||
// Квартира или офис
|
||||
|
||||
block : varchar(20)
|
||||
// Корпус или строение
|
||||
|
||||
city : varchar(100) <<NN>>
|
||||
// Город или населенный пункт
|
||||
|
||||
country : varchar(100) <<NN>>
|
||||
// Страна
|
||||
|
||||
district : varchar(100)
|
||||
// Район
|
||||
|
||||
entrance : varchar(10)
|
||||
// Подъезд
|
||||
|
||||
entryphone : varchar(20)
|
||||
// Код домофона
|
||||
|
||||
postcode : varchar(20)
|
||||
// Почтовый индекс (для почтовой доставки)
|
||||
|
||||
floor : varchar(5)
|
||||
// Этаж
|
||||
|
||||
house : varchar(10)
|
||||
// Дом или владение
|
||||
|
||||
phone : varchar(20) <<NN>>
|
||||
// Телефон получателя заказа
|
||||
|
||||
street : varchar(255)
|
||||
// Улица
|
||||
|
||||
recipient : varchar(255) <<NN>>
|
||||
// ФИО получателя заказа
|
||||
|
||||
latitude : double precision <<NN>>
|
||||
// Широта адреса доставки
|
||||
|
||||
longitude : double precision <<NN>>
|
||||
// Долгота адреса доставки
|
||||
}
|
||||
|
||||
entity "order_item" as item {
|
||||
id : bigint <<PK>> <<NN>> autoincrement
|
||||
// Идентификатор записи
|
||||
--
|
||||
t_shop_item_id : bigint <<NN>>
|
||||
// Идентификатор товара в заказе (позволяет идентифицировать товар в заказе)
|
||||
|
||||
order_id : bigint <<NN>>
|
||||
// Ссылка на заказ
|
||||
|
||||
count : integer <<NN>>
|
||||
// Количество единиц товара
|
||||
|
||||
product_id : varchar(255) <<NN>>
|
||||
// SKU (наш внутренний)
|
||||
|
||||
offer_name : varchar(500)
|
||||
// Название товара
|
||||
|
||||
price : numeric(10,2) <<NN>>
|
||||
// Цена товара в рублях
|
||||
}
|
||||
|
||||
' === СВЯЗИ ===
|
||||
order ||--|| buyer : "1:1\n(обязательно)"
|
||||
order ||--o| delivery : "1:1\n(необязательно)"
|
||||
delivery ||--|| address : "1:1\n(необязательно)"
|
||||
order ||--|{ item : "1:many\n(обязательно)"
|
||||
outlet ||--o{ delivery : "1:many\n(необязательно)"
|
||||
order ||--o{ order_status_history : "1:many\n(обязательно)"
|
||||
|
||||
note left of order
|
||||
<u><b>order_status_type</b></u>
|
||||
<b>Статус</b> <b>Описание</b>
|
||||
CANCELLED Отменен
|
||||
PROCESSING В обработке
|
||||
DELIVERY В службе доставки
|
||||
PICKUP В пункте самовывоза
|
||||
DELIVERED Получен покупателем
|
||||
===
|
||||
<u><b>order_substatus_type</b></u>
|
||||
<b>Этап</b> <b>Статус</b> <b>Описание</b>
|
||||
STARTED (статус-> PROCESSING Заказ подтвержден, можно обрабатывать
|
||||
READY_TO_SHIP (статус-> PROCESSING Заказ собран, готов к отправке
|
||||
SHOP_FAILED (статус-> CANCELLED Магазин не может выполнить
|
||||
USER_CHANGED_MIND (статус-> CANCELLED Покупатель отменил
|
||||
endnote
|
||||
|
||||
note top of delivery
|
||||
<u><b>order_lift_type</b></u>
|
||||
<b>Тип Описание</b>
|
||||
NOT_NEEDED Не требуется
|
||||
MANUAL Ручной
|
||||
ELEVATOR Лифт
|
||||
CARGO_ELEVATOR Грузовой лифт
|
||||
FREE Любой (при бесплатном подъеме)
|
||||
UNKNOWN Неизвестный тип
|
||||
===
|
||||
<u><b>order_delivery_type</b></u>
|
||||
<b>Тип Описание</b>
|
||||
DELIVERY Курьерская доставка
|
||||
PICKUP Самовывоз
|
||||
UNKNOWN Неизвестный тип
|
||||
endnote
|
||||
|
||||
|
||||
@enduml
|
||||
68
oms/t-shop/get-order.puml
Normal file
68
oms/t-shop/get-order.puml
Normal file
@@ -0,0 +1,68 @@
|
||||
@startuml
|
||||
title Flow: Получение и обработка заказов с маркетплейса
|
||||
|
||||
actor "Покупатель" as Customer
|
||||
participant "T-Shop\n(Маркетплейс)" as TShop
|
||||
participant "T-Shop-ADP\n(Адаптер)" as Adapter
|
||||
database "T-Shop-ADP-DB\n(sync_state, orders)" as DB
|
||||
participant "Superset" as Superset
|
||||
actor "Менеджер ВИ" as Admin
|
||||
|
||||
== Покупатель оформляет заказ ==
|
||||
|
||||
Customer -> TShop: Оформление заказа
|
||||
note right of TShop: Статус заказа:\nstatus = "PROCESSING"\nsubstatus = "STARTED"
|
||||
TShop --> Customer:
|
||||
|
||||
== Периодическая синхронизация заказов (Дельта по updatedAt) ==
|
||||
|
||||
loop Каждые 15 минут
|
||||
|
||||
Adapter -> DB: Чтение состояния синхронизации\n(sync_log.last_synced_updated_at)
|
||||
DB --> Adapter: last_synced_updated_at
|
||||
|
||||
Adapter -> TShop: **GET /orders?updatedAtFrom=last_synced_updated_at-5min&updatedAtTo=now()-2min&limit=50**
|
||||
|
||||
TShop --> Adapter: Ответ с пагинацией\norders[...], nextPageToken="abc123"
|
||||
|
||||
loop Пока есть nextPageToken
|
||||
|
||||
Adapter -> DB: **UPSERT заказов в БД**
|
||||
note right of Adapter: Insert новых\nUpdate существующих (по updatedAt)
|
||||
DB --> Adapter:
|
||||
|
||||
Adapter -> TShop: Следующий запрос с pageToken
|
||||
TShop --> Adapter: Следующая порция заказов
|
||||
end
|
||||
|
||||
Adapter -> DB: Обновить sync_log\nlast_synced_updated_at = updatedAtTo
|
||||
DB --> Adapter:
|
||||
|
||||
end
|
||||
|
||||
== Обновление Superset ==
|
||||
Superset -> DB: Автообновление дашборда\n(через прямое подключение)
|
||||
DB --> Superset: Актуальные данные
|
||||
|
||||
== Работа менеджера (Оформление заказов) ==
|
||||
|
||||
Admin -> Superset: Открытие дашборда
|
||||
Superset -> DB: Запрос данных
|
||||
DB --> Superset:
|
||||
Superset --> Admin: Отображение заказов
|
||||
|
||||
Admin -> Admin: Ручное оформление заказа\nв АРМ системе
|
||||
|
||||
== Работа менеджера (Обновление статуса заказа) ==
|
||||
|
||||
Admin -> Adapter: Обновление статуса заказа в T-Shop через Postman
|
||||
Adapter -> Adapter: Подстановка кредов + обработка параметров входящих
|
||||
Adapter --> TShop: Отправка запроса
|
||||
|
||||
== Работа менеджера (Отправка кода получения заказа) ==
|
||||
|
||||
Admin -> Adapter: Отправка кода получения в T-Shop через Postman
|
||||
Adapter -> Adapter: Подстановка кредов + обработка параметров входящих
|
||||
Adapter --> TShop: Отправка запроса
|
||||
|
||||
@enduml
|
||||
Reference in New Issue
Block a user