Інтеграція з Мурашина логістика в Python
Головна ідея: розробити Python-сервіс, який інтегрує K2 ERP / CRM / інтернет-магазин / WMS із сервісом Мурашина логістика / ANT-Logistics для передачі заявок на доставку, торгових точок, складів, автомобілів, водіїв, товарів, маршрутів, статусів доставки та фактичних результатів виконання.
Критично важливо: інтеграція з логістичною системою не повинна втрачати заявки на доставку. Кожне замовлення, точка доставки, маршрут, зміна статусу, помилка API та повторна передача повинні мати внутрішній ID, журнал подій і захист від дублювання.
Важливо: точні endpoint-и ANT-Logistics потрібно брати з офіційної API-документації, доступної в кабінеті або довідковому центрі. У цьому ТЗ endpoint-и Python-сервісу є внутрішніми, а зовнішні методи ANT-Logistics повинні бути уточнені під API v2.
Технічний стек: Python 3.11+, FastAPI, PostgreSQL, SQLAlchemy, Alembic, httpx, Pydantic, Celery/RQ/APScheduler, Redis, Docker.
Управлінський результат: логіст і керівник повинні бачити, які заявки передано в ANT-Logistics, які маршрути сформовано, які замовлення доставлено, які не виконано, які водії мають відхилення, які точки проблемні та де потрібне втручання.
1. Мета
Метою задачі є створення Python-сервісу для інтеграції з сервісом Мурашина логістика / ANT-Logistics з метою автоматизації транспортної логістики.
Сервіс повинен забезпечити:
- передачу торгових точок / клієнтів;
- передачу заявок на доставку;
- передачу складів / сервісних точок;
- передачу автомобілів;
- передачу водіїв або співробітників;
- передачу товарів або вантажних параметрів;
- запуск або підготовку планування маршрутів;
- отримання маршрутів;
- отримання статусів маршрутів;
- отримання статусів виконання точок доставки;
- отримання фактичних даних виконання;
- обмін із GPS-трекерами, якщо використовується;
- синхронізацію результатів назад у K2 ERP;
- журналювання всіх запитів;
- контроль помилок;
- dashboard для логіста і керівника.
2. Область застосування
Інтеграція призначена для:
- служб доставки;
- дистриб'юторів;
- торгових компаній;
- інтернет-магазинів;
- виробничих компаній із власною доставкою;
- логістичних підрозділів;
- компаній із мобільними торговими представниками;
- компаній, які використовують маршрутизацію водіїв або кур'єрів;
- компаній, які ведуть замовлення в K2 ERP і планують маршрути в ANT-Logistics.
3. Джерела інтеграції
| Компонент | Призначення | Коментар |
|---|---|---|
| K2 ERP / CRM / WMS / інтернет-магазин | Джерело замовлень, клієнтів, товарів і складів. | Внутрішня система замовника. |
| Python Integration Service | Інтеграційний шар між K2 ERP та ANT-Logistics. | Реалізується в межах цього ТЗ. |
| ANT-Logistics / Мурашина логістика | Сервіс планування оптимальних маршрутів доставки. | Зовнішня логістична система. |
| Мобільний додаток водія | Водій бачить маршрут, точки та може працювати з навігацією. | Використовується на стороні ANT-Logistics. |
| GPS-трекери | Джерело фактичного руху автомобілів. | Може інтегруватись через ANT-Logistics або окремо. |
| Dashboard K2 ERP | Контроль передачі, маршрутів, статусів і помилок. | Внутрішній контроль для логіста та керівника. |
4. Передумови
Для реалізації задачі необхідно отримати:
- акаунт ANT-Logistics;
- доступ до API v2;
- API key або інший ключ доступу;
- механізм отримання ідентифікатора сесії, якщо він використовується API;
- тестове середовище або тестовий акаунт;
- список доступних API-методів;
- структуру даних для торгових точок;
- структуру даних для автомобілів;
- структуру даних для складів;
- структуру даних для завдань / заявок;
- правила маршрутизації;
- правила імпорту та експорту;
- перелік статусів маршрутів і задач;
- правила роботи з GPS;
- правила авторизації;
- ліміти API;
- контакт технічної підтримки ANT-Logistics.
Критично важливо: до початку розробки потрібно отримати реальну API-документацію ANT-Logistics v2 і перевірити методи створення / оновлення точок, машин, складів, завдань, маршрутів і статусів.
5. Основні бізнес-сценарії
5.1. Передача замовлень на доставку
K2 ERP формує список замовлень, які потрібно доставити, і передає їх у Python-сервіс.
Python-сервіс:
- перевіряє дані замовлення;
- визначає точку доставки;
- формує заявку / задачу для ANT-Logistics;
- передає адресу, координати, часове вікно, вагу, об'єм, суму, контакт;
- зберігає ID задачі ANT-Logistics;
- очікує включення задачі в маршрут.
5.2. Синхронізація торгових точок
K2 ERP передає в ANT-Logistics список клієнтів або торгових точок.
Використовується для:
- постійних клієнтів;
- магазинів;
- точок доставки;
- геокодування адрес;
- прив'язки замовлень до існуючих точок;
- групування точок;
- планування регулярних маршрутів.
5.3. Синхронізація автомобілів
K2 ERP або TMS передає перелік автомобілів.
Поля:
- номер автомобіля;
- вантажопідйомність;
- об'єм;
- тип кузова;
- доступність;
- водій;
- графік роботи;
- склад старту;
- склад завершення;
- група автомобілів.
5.4. Планування маршрутів
ANT-Logistics виконує розрахунок оптимальних маршрутів.
Python-сервіс повинен:
- передати задачі на дату;
- перевірити успішність імпорту;
- отримати список маршрутів;
- отримати порядок точок у маршруті;
- зберегти маршрут у K2 ERP;
- сформувати задачі водіям або логісту;
- показати маршрут у dashboard.
5.5. Отримання статусів доставки
Після виконання маршруту Python-сервіс повинен отримати:
- статус маршруту;
- статус кожної точки;
- фактичний час прибуття;
- фактичний час від'їзду;
- причину недоставки;
- коментар водія;
- фото / вкладення, якщо доступні;
- GPS-факт, якщо доступний;
- суму післяплати, якщо використовується.
6. Основні сутності
| Сутність | Опис |
|---|---|
| Integration Account | Налаштування підключення до ANT-Logistics. |
| Delivery Point | Торгова точка, клієнт або адреса доставки. |
| Warehouse | Склад або сервісна точка. |
| Vehicle | Автомобіль. |
| Driver | Водій або кур'єр. |
| Product / Cargo | Товар або вантажні параметри. |
| Delivery Order | Замовлення на доставку з K2 ERP. |
| ANT Task | Задача / точка доставки в ANT-Logistics. |
| Route | Маршрут, сформований у ANT-Logistics. |
| Route Stop | Окрема точка маршруту. |
| Delivery Status | Статус доставки. |
| GPS Track | Фактичний рух автомобіля. |
| API Event | Подія інтеграції. |
7. User Story
7.1. Передача заявки
Як логіст, я хочу передати замовлення з K2 ERP у Мурашину логістику, щоб система врахувала їх під час планування маршрутів.
7.2. Планування маршруту
Як логіст, я хочу отримати з ANT-Logistics сформовані маршрути, щоб бачити порядок доставки, водіїв, автомобілі та плановий час прибуття.
7.3. Контроль виконання
Як керівник доставки, я хочу бачити статуси виконання по маршрутах і точках, щоб контролювати проблемні доставки та відхилення.
7.4. Робота водія
Як водій, я хочу бачити свій маршрут у мобільному додатку ANT-Logistics, щоб виконувати доставку в правильному порядку.
7.5. Повернення статусів у K2 ERP
Як менеджер, я хочу бачити в K2 ERP, що замовлення доставлено або не доставлено, щоб коректно закривати документи, оплату та взаєморозрахунки.
8. Типи даних для передачі
8.1. Торгові точки / клієнти
| Поле | Тип | Обов'язковість | Опис |
|---|---|---|---|
| external_point_id | string | Так | ID точки в K2 ERP. |
| name | string | Так | Назва клієнта або торгової точки. |
| address | string | Так | Адреса доставки. |
| latitude | decimal | Ні | Широта. |
| longitude | decimal | Ні | Довгота. |
| contact_name | string | Ні | Контактна особа. |
| phone | string | Ні | Телефон. |
| string | Ні | Email. | |
| group | string | Ні | Група точок. |
| service_time_minutes | integer | Ні | Час обслуговування точки. |
| time_window_from | time | Ні | Початок часового вікна. |
| time_window_to | time | Ні | Кінець часового вікна. |
8.2. Замовлення / заявка на доставку
| Поле | Тип | Обов'язковість | Опис |
|---|---|---|---|
| external_order_id | string | Так | ID замовлення в K2 ERP. |
| idempotency_key | string | Так | Ключ захисту від дублювання. |
| delivery_date | date | Так | Дата доставки. |
| point_id | string | Так | ID торгової точки. |
| address | string | Так | Адреса доставки. |
| latitude | decimal | Ні | Широта. |
| longitude | decimal | Ні | Довгота. |
| weight | decimal | Ні | Вага. |
| volume | decimal | Ні | Об'єм. |
| amount | decimal | Ні | Сума замовлення. |
| payment_type | enum | Ні | Готівка, картка, післяплата, безготівка. |
| comment | text | Ні | Коментар для логіста або водія. |
| time_window_from | time | Ні | Початок часового вікна. |
| time_window_to | time | Ні | Кінець часового вікна. |
| priority | integer | Ні | Пріоритет доставки. |
8.3. Автомобіль
| Поле | Тип | Опис |
|---|---|---|
| external_vehicle_id | string | ID автомобіля в K2 ERP. |
| name | string | Назва або номер. |
| plate_number | string | Державний номер. |
| capacity_weight | decimal | Вантажопідйомність. |
| capacity_volume | decimal | Об'єм. |
| vehicle_type | string | Тип авто. |
| driver_id | string | Закріплений водій. |
| start_warehouse_id | string | Початковий склад. |
| finish_warehouse_id | string | Кінцева точка. |
| is_active | boolean | Чи активний автомобіль. |
8.4. Водій / кур'єр
| Поле | Тип | Опис |
|---|---|---|
| external_driver_id | string | ID водія в K2 ERP. |
| name | string | ПІБ. |
| phone | string | Телефон. |
| string | Email. | |
| vehicle_id | string | Закріплений автомобіль. |
| work_time_from | time | Початок робочого часу. |
| work_time_to | time | Кінець робочого часу. |
| is_active | boolean | Активність. |
9. Статуси доставки
| Статус | Код | Опис | Колір |
|---|---|---|---|
| Чернетка | DRAFT | Заявка створена в K2 ERP, але ще не передана. | Сірий |
| Очікує передачі | PENDING_SEND | Заявка в черзі на передачу. | Жовтий |
| Передається | SENDING | Виконується API-запит. | Блакитний |
| Передано в ANT | SENT_TO_ANT | Заявка успішно передана. | Блакитний |
| Заплановано | PLANNED | Заявку включено в маршрут. | Зелений |
| В маршруті | IN_ROUTE | Водій виконує маршрут. | Блакитний |
| Доставлено | DELIVERED | Замовлення доставлено. | Зелений |
| Не доставлено | NOT_DELIVERED | Замовлення не доставлено. | Червоний |
| Частково доставлено | PARTIALLY_DELIVERED | Доставлено не всі позиції або не вся кількість. | Помаранчевий |
| Відмовлено | REJECTED_BY_CLIENT | Клієнт відмовився від доставки. | Червоний |
| Потребує повтору | NEEDS_RETRY | Технічна помилка, можна повторити. | Помаранчевий |
| Помилка передачі | SEND_ERROR | API повернув помилку. | Червоний |
| Скасовано | CANCELLED | Заявку скасовано. | Сірий |
10. Єдина логіка кольорів
| Колір | HTML | Значення | Де використовується |
|---|---|---|---|
| Зелений | #c8e6c9 | Успішно: доставлено, заплановано, виконано. | Dashboard, список доставок, маршрут. |
| Блакитний | #bbdefb | Операція в роботі. | Передача, маршрут, виконання. |
| Жовтий | #fff9c4 | Очікування дії або планування. | Черга, очікування маршруту. |
| Помаранчевий | #ffcc80 | Потрібна дія або є ризик. | Retry, часткова доставка, відхилення. |
| Червоний | #ef9a9a | Помилка або невиконання. | Помилки API, недоставка. |
| Фіолетовий | #f3e5f5 | Спеціальний статус або ручна перевірка. | Ручна обробка, нестандартні маршрути. |
| Сірий | #eeeeee | Чернетка, скасовано або неактивно. | Архів, чернетки. |
11. Архітектура рішення
11.1. Загальна схема
K2 ERP / CRM / WMS / Website
|
| 1. Замовлення, точки, склади, авто, водії
v
Python ANT-Logistics Integration Service
|
| 2. Валідація, мапінг, дедублікація, черга
v
ANT-Logistics Client
|
| 3. API v2 ANT-Logistics
v
Мурашина логістика / ANT-Logistics
|
| 4. Планування маршрутів, мобільний додаток водія, GPS
v
Водій / Кур'єр / Логіст
|
| 5. Статуси виконання, фактичні дані
v
Python Status Sync Worker
|
| 6. Оновлення статусів
v
K2 ERP / Dashboard / Документи / Замовлення
11.2. Основні компоненти Python-сервісу
| Компонент | Опис |
|---|---|
| API Layer | REST API для прийому заявок, точок, авто, водіїв. |
| Data Validator | Перевіряє адреси, координати, дати, вагу, об'єм, часові вікна. |
| Mapping Layer | Перетворює структури K2 ERP у структури ANT-Logistics. |
| ANT-Logistics Client | Python-клієнт для API ANT-Logistics. |
| Delivery Queue | Черга передачі заявок. |
| Route Sync Worker | Отримує маршрути та точки маршрутів. |
| Status Sync Worker | Отримує статуси доставок. |
| GPS Sync Worker | Отримує фактичні треки, якщо доступно. |
| Audit Logger | Зберігає всі запити, відповіді та помилки. |
| Dashboard API | Дані для логіста, керівника та диспетчера. |
12. ANT-Logistics Client
12.1. Призначення
ANT-Logistics Client — це Python-клас або пакет, який інкапсулює роботу з API ANT-Logistics.
12.2. Основні методи
class AntLogisticsClient:
def check_connection(self) -> "ConnectionStatus":
pass
def authenticate(self) -> "AuthResult":
pass
def refresh_session(self) -> "AuthResult":
pass
def create_or_update_point(self, payload: "DeliveryPointPayload") -> "AntPointResponse":
pass
def create_or_update_vehicle(self, payload: "VehiclePayload") -> "AntVehicleResponse":
pass
def create_or_update_driver(self, payload: "DriverPayload") -> "AntDriverResponse":
pass
def create_or_update_warehouse(self, payload: "WarehousePayload") -> "AntWarehouseResponse":
pass
def create_delivery_task(self, payload: "DeliveryTaskPayload") -> "AntTaskResponse":
pass
def update_delivery_task(self, ant_task_id: str, payload: "DeliveryTaskPayload") -> "AntTaskResponse":
pass
def cancel_delivery_task(self, ant_task_id: str, reason: str) -> "CancelTaskResponse":
pass
def get_routes(self, delivery_date: str) -> "RouteListResponse":
pass
def get_route(self, ant_route_id: str) -> "RouteResponse":
pass
def get_task_status(self, ant_task_id: str) -> "TaskStatusResponse":
pass
def get_route_status(self, ant_route_id: str) -> "RouteStatusResponse":
pass
Важливо: методи Python-клієнта є внутрішньою абстракцією. Реальні API-методи ANT-Logistics потрібно взяти з офіційної API v2-документації.
12.3. Конфігурація клієнта
from pydantic_settings import BaseSettings
class AntLogisticsSettings(BaseSettings):
base_url: str
api_key: str
session_id: str | None = None
account_id: str | None = None
integration_mode: str = "api_v2"
timeout_seconds: int = 30
retry_count: int = 3
retry_backoff_seconds: int = 5
verify_ssl: bool = True
Приклад `.env`:
ANT_LOGISTICS_BASE_URL=https://api.example.ant-logistics ANT_LOGISTICS_API_KEY=******** ANT_LOGISTICS_ACCOUNT_ID=account-001 ANT_LOGISTICS_INTEGRATION_MODE=api_v2 ANT_LOGISTICS_TIMEOUT_SECONDS=30 ANT_LOGISTICS_RETRY_COUNT=3 ANT_LOGISTICS_RETRY_BACKOFF_SECONDS=5
Заборонено: зберігати API key, session ID або інші секрети у коді, Git-репозиторії, відкритих логах або frontend-змінних.
13. API Python-сервісу
13.1. Створення інтеграції
POST /api/v1/ant-logistics/integrations
13.2. Перевірка підключення
POST /api/v1/ant-logistics/integrations/{integration_id}/check-connection
13.3. Синхронізація торгової точки
POST /api/v1/ant-logistics/points/sync
13.4. Синхронізація автомобіля
POST /api/v1/ant-logistics/vehicles/sync
13.5. Синхронізація водія
POST /api/v1/ant-logistics/drivers/sync
13.6. Синхронізація складу
POST /api/v1/ant-logistics/warehouses/sync
13.7. Створення заявки на доставку
POST /api/v1/ant-logistics/delivery-orders
13.8. Передача заявки в ANT-Logistics
POST /api/v1/ant-logistics/delivery-orders/{order_id}/send
13.9. Скасування заявки
POST /api/v1/ant-logistics/delivery-orders/{order_id}/cancel
13.10. Синхронізація маршруту
POST /api/v1/ant-logistics/routes/sync
13.11. Синхронізація статусів
POST /api/v1/ant-logistics/statuses/sync
13.12. Dashboard
GET /api/v1/ant-logistics/dashboard?date_from=2026-05-01&date_to=2026-05-31
14. Приклад запиту на створення заявки
{
"external_order_id": "K2-ORDER-2026-000123",
"idempotency_key": "K2-ORDER-2026-000123-delivery-v1",
"delivery_date": "2026-05-08",
"point": {
"external_point_id": "CLIENT-001",
"name": "ТОВ «Альфа»",
"address": "м. Київ, вул. Хрещатик, 1",
"latitude": 50.4501,
"longitude": 30.5234,
"contact_name": "Іван Петренко",
"phone": "+380501112233",
"service_time_minutes": 15,
"time_window_from": "09:00",
"time_window_to": "13:00"
},
"cargo": {
"weight": 120.5,
"volume": 0.8,
"places": 4
},
"payment": {
"amount": 5700.00,
"payment_type": "cash_on_delivery"
},
"comment": "Зателефонувати за 30 хвилин до прибуття",
"priority": 5
}
15. Валідація заявки
Перед передачею в ANT-Logistics система повинна перевірити:
- наявність external_order_id;
- наявність idempotency_key;
- дату доставки;
- адресу доставки;
- координати або можливість геокодування;
- контактний телефон;
- часові вікна;
- вагу;
- об'єм;
- кількість місць;
- суму післяплати, якщо є;
- склад відвантаження;
- активність точки;
- чи не була заявка вже передана;
- чи дозволено змінювати заявку після планування;
- чи немає скасування в K2 ERP.
Критично важливо: заявка, яка вже включена в маршрут або виконана водієм, не повинна автоматично змінюватись без окремого правила. Зміни після планування можуть вплинути на весь маршрут.
16. Дедублікація
Система повинна не допускати дублювання заявок.
Ключі дедублікації:
| Ключ | Призначення |
|---|---|
| external_order_id | ID замовлення у K2 ERP. |
| idempotency_key | Унікальний ключ конкретної версії передачі. |
| ant_task_id | ID задачі в ANT-Logistics. |
| delivery_date + point_id + order_number | Бізнес-ключ доставки. |
Приклад hash:
sha256(external_order_id + delivery_date + point_id + address + amount)
17. Черга передачі
Для надійності передача заявок повинна виконуватись через чергу.
17.1. Логіка черги
1. K2 ERP створює замовлення на доставку. 2. Python-сервіс виконує валідацію. 3. Створюється delivery_order зі статусом DRAFT або PENDING_SEND. 4. Worker передає точку доставки в ANT-Logistics. 5. Worker передає заявку / задачу. 6. ANT-Logistics повертає ID задачі. 7. Python-сервіс зберігає ant_task_id. 8. Status Sync Worker оновлює статуси. 9. Route Sync Worker отримує маршрути. 10. K2 ERP отримує фінальний статус доставки.
17.2. Пріоритети задач
| Тип задачі | Пріоритет | Коментар |
|---|---|---|
| Передача заявки на доставку | Високий | Основний бізнес-процес. |
| Скасування заявки | Високий | Важливо до початку маршруту. |
| Оновлення адреси / часу | Високий | Може вплинути на маршрут. |
| Синхронізація маршрутів | Середній | Фоновий процес. |
| Синхронізація статусів | Середній | Фоновий процес. |
| Синхронізація довідників | Низький | Точки, авто, водії, товари. |
18. Модель даних
18.1. ant_integrations
| Поле | Тип | Опис |
|---|---|---|
| id | uuid | ID інтеграції. |
| provider | varchar | ant_logistics. |
| integration_mode | varchar | api_v2. |
| name | varchar | Назва інтеграції. |
| base_url | varchar | URL API. |
| api_key_encrypted | text | Зашифрований API key. |
| session_id_encrypted | text | Зашифрований session ID, якщо використовується. |
| account_id | varchar | ID акаунта. |
| is_active | boolean | Активність. |
| created_at | timestamp | Дата створення. |
| updated_at | timestamp | Дата оновлення. |
18.2. ant_delivery_points
| Поле | Тип | Опис |
|---|---|---|
| id | uuid | Внутрішній ID точки. |
| external_point_id | varchar | ID точки в K2 ERP. |
| ant_point_id | varchar | ID точки в ANT-Logistics. |
| name | varchar | Назва. |
| address | text | Адреса. |
| latitude | numeric | Широта. |
| longitude | numeric | Довгота. |
| contact_name | varchar | Контактна особа. |
| phone | varchar | Телефон. |
| group_name | varchar | Група. |
| status | varchar | Статус синхронізації. |
18.3. ant_delivery_orders
| Поле | Тип | Опис |
|---|---|---|
| id | uuid | ID заявки. |
| external_order_id | varchar | ID замовлення K2 ERP. |
| idempotency_key | varchar | Ключ дедублікації. |
| ant_task_id | varchar | ID задачі в ANT-Logistics. |
| delivery_date | date | Дата доставки. |
| point_id | uuid | Точка доставки. |
| address | text | Адреса. |
| weight | numeric | Вага. |
| volume | numeric | Об'єм. |
| places | integer | Кількість місць. |
| amount | numeric | Сума. |
| payment_type | varchar | Тип оплати. |
| status | varchar | Поточний статус. |
| ant_status | varchar | Оригінальний статус ANT. |
| route_id | uuid | Маршрут. |
| raw_request | jsonb | Запит. |
| raw_response | jsonb | Відповідь. |
| error_message | text | Помилка. |
| sent_at | timestamp | Дата передачі. |
| delivered_at | timestamp | Дата доставки. |
18.4. ant_routes
| Поле | Тип | Опис |
|---|---|---|
| id | uuid | ID маршруту. |
| ant_route_id | varchar | ID маршруту в ANT-Logistics. |
| delivery_date | date | Дата маршруту. |
| vehicle_id | uuid | Автомобіль. |
| driver_id | uuid | Водій. |
| status | varchar | Статус маршруту. |
| planned_distance | numeric | Планова відстань. |
| planned_duration | integer | Планова тривалість. |
| fact_distance | numeric | Фактична відстань. |
| fact_duration | integer | Фактична тривалість. |
| started_at | timestamp | Початок маршруту. |
| finished_at | timestamp | Завершення маршруту. |
18.5. ant_route_stops
| Поле | Тип | Опис |
|---|---|---|
| id | uuid | ID точки маршруту. |
| route_id | uuid | Маршрут. |
| delivery_order_id | uuid | Заявка. |
| sequence_number | integer | Порядок точки. |
| planned_arrival_at | timestamp | Планове прибуття. |
| fact_arrival_at | timestamp | Фактичне прибуття. |
| fact_departure_at | timestamp | Фактичний виїзд. |
| status | varchar | Статус точки. |
| comment | text | Коментар. |
18.6. ant_events
| Поле | Тип | Опис |
|---|---|---|
| id | uuid | ID події. |
| entity_type | varchar | integration, point, order, route, stop. |
| entity_id | uuid | ID сутності. |
| event_type | varchar | Тип події. |
| old_status | varchar | Попередній статус. |
| new_status | varchar | Новий статус. |
| source | varchar | K2_ERP, PYTHON_SERVICE, ANT_LOGISTICS, USER. |
| payload | jsonb | Технічні дані. |
| created_at | timestamp | Дата події. |
19. Приклад Python-логіки
19.1. Створення заявки
def create_delivery_order(command: "CreateDeliveryOrderCommand", db: "Session") -> "DeliveryOrder":
existing = delivery_order_repository.get_by_idempotency_key(
db=db,
idempotency_key=command.idempotency_key,
)
if existing:
return existing
delivery_validator.validate(command)
order = delivery_order_repository.create(
db=db,
data={
"external_order_id": command.external_order_id,
"idempotency_key": command.idempotency_key,
"delivery_date": command.delivery_date,
"address": command.point.address,
"weight": command.cargo.weight,
"volume": command.cargo.volume,
"places": command.cargo.places,
"amount": command.payment.amount,
"payment_type": command.payment.payment_type,
"status": "PENDING_SEND",
"raw_request": command.model_dump(),
},
)
delivery_queue.enqueue(
task_name="send_delivery_order_to_ant",
payload={"delivery_order_id": str(order.id)},
)
audit_logger.log(
entity_type="delivery_order",
entity_id=order.id,
event_type="DELIVERY_ORDER_CREATED",
new_status="PENDING_SEND",
payload={"external_order_id": command.external_order_id},
)
db.commit()
return order
19.2. Передача заявки в ANT-Logistics
def send_delivery_order_to_ant(delivery_order_id: str, db: "Session") -> None:
order = delivery_order_repository.get_by_id(db, delivery_order_id)
if order.status in ["SENT_TO_ANT", "PLANNED", "DELIVERED"]:
return
try:
order.status = "SENDING"
db.commit()
point_payload = ant_mapper.to_point_payload(order)
point_response = ant_client.create_or_update_point(point_payload)
task_payload = ant_mapper.to_task_payload(order, point_response.point_id)
task_response = ant_client.create_delivery_task(task_payload)
order.ant_task_id = task_response.task_id
order.status = "SENT_TO_ANT"
order.raw_response = task_response.raw_payload
order.sent_at = utc_now()
audit_logger.log(
entity_type="delivery_order",
entity_id=order.id,
event_type="DELIVERY_ORDER_SENT_TO_ANT",
old_status="SENDING",
new_status="SENT_TO_ANT",
payload={"ant_task_id": task_response.task_id},
)
except TemporaryAntError as exc:
order.status = "NEEDS_RETRY"
order.error_message = str(exc)
except Exception as exc:
order.status = "SEND_ERROR"
order.error_message = str(exc)
finally:
db.commit()
19.3. Синхронізація статусу
def sync_delivery_order_status(delivery_order_id: str, db: "Session") -> None:
order = delivery_order_repository.get_by_id(db, delivery_order_id)
if not order.ant_task_id:
return
status_response = ant_client.get_task_status(order.ant_task_id)
old_status = order.status
new_status = status_mapper.from_ant(status_response.status)
if old_status != new_status:
order.status = new_status
order.ant_status = status_response.status
if new_status == "DELIVERED":
order.delivered_at = status_response.fact_finished_at
audit_logger.log(
entity_type="delivery_order",
entity_id=order.id,
event_type="DELIVERY_STATUS_SYNCED",
old_status=old_status,
new_status=new_status,
payload=status_response.raw_payload,
)
db.commit()
20. Обробка помилок
20.1. Типи помилок
| Тип помилки | Опис | Дія системи |
|---|---|---|
| ValidationError | Некоректні дані заявки. | Не передавати заявку, показати список помилок. |
| AuthError | Невірний API key або session ID. | Зупинити інтеграцію, повідомити адміністратора. |
| AddressError | Некоректна адреса або не визначені координати. | Перевести в NEEDS_CORRECTION. |
| GeoCodingError | Не вдалося визначити координати. | Передати на ручну перевірку. |
| CapacityError | Вага або об'єм перевищує можливості транспорту. | Показати логісту. |
| SendError | API повернув помилку. | Зберегти raw-відповідь. |
| TimeoutError | Перевищено час очікування. | Перевести в NEEDS_RETRY. |
| DuplicateOrderError | Заявка вже передана. | Повернути існуючу заявку. |
| RouteLockedError | Маршрут уже зафіксований. | Заборонити автоматичну зміну. |
20.2. Retry-логіка
Retry дозволений для:
- timeout;
- HTTP 429;
- HTTP 500;
- HTTP 502;
- HTTP 503;
- HTTP 504;
- тимчасової недоступності ANT-Logistics;
- тимчасової помилки отримання статусу;
- тимчасової помилки синхронізації маршрутів.
Retry заборонений для:
- помилок валідації;
- неправильного API key;
- некоректної адреси;
- заявки, яка вже доставлена;
- заявки, яка скасована;
- маршруту, який уже зафіксований або виконується, якщо зміни заборонені.
21. Dashboard логіста і керівника
21.1. Основні KPI
| KPI | Опис | Колір |
|---|---|---|
| Заявок створено | Загальна кількість заявок за період. | Інформація |
| Передано в ANT | Заявки, які успішно передані. | В роботі |
| Заплановано | Заявки включено в маршрути. | Норма |
| Доставлено | Успішно виконані доставки. | Норма |
| Не доставлено | Проблемні доставки. | Критично |
| Частково доставлено | Є відхилення по кількості або сумі. | Потрібна дія |
| Потребують повтору | Технічні помилки передачі. | Потрібна дія |
| Без координат | Точки, які потребують геокодування. | Увага |
21.2. Приклад dashboard
| Показник | Значення | Стан |
|---|---|---|
| Заявок на сьогодні | 348 | Інформація |
| Передано в ANT | 340 | В роботі |
| Заплановано | 328 | Норма |
| Доставлено | 280 | Норма |
| Не доставлено | 12 | Критично |
| Частково доставлено | 6 | Потрібна дія |
| Потребують повтору | 4 | Потрібна дія |
| Без координат | 9 | Увага |
21.3. Проблемні доставки
| Дата | Замовлення | Клієнт | Водій | Статус | Причина | Дія |
|---|---|---|---|---|---|---|
| 08.05.2026 | K2-ORDER-123 | ТОВ «Альфа» | Іваненко О.М. | Не доставлено | Клієнт відсутній | Перенести доставку |
| 08.05.2026 | K2-ORDER-124 | ФОП Петренко | Сидоренко А.В. | Частково доставлено | Частина товару відсутня | Перевірити залишки |
| 08.05.2026 | K2-ORDER-125 | ТОВ «Бета» | - | Без координат | Не знайдено адресу | Геокодувати вручну |
22. Безпека
Система повинна забезпечити:
- зберігання API key тільки у secret storage або в зашифрованому вигляді;
- заборону логування API key та session ID;
- HTTPS для всіх API-запитів;
- перевірку SSL;
- рольову модель доступу;
- окремі права на відправку заявок;
- окремі права на скасування заявок;
- окремі права на повторну передачу;
- журнал усіх дій;
- захист від дублювання заявок;
- маскування персональних даних клієнтів у логах;
- контроль доступу до GPS-даних.
23. Логування та аудит
Система повинна логувати:
| Подія | Що зберігати |
|---|---|
| Створення заявки | Замовлення, клієнт, дата доставки, сума. |
| Валідація | Результат, список помилок. |
| Передача точки | Дані точки, ANT point ID. |
| Передача заявки | Час, endpoint, request ID, ANT task ID. |
| Отримання маршруту | ANT route ID, водій, автомобіль, точки. |
| Отримання статусу | Старий статус, новий статус, джерело. |
| Помилка передачі | Код, повідомлення, raw-відповідь. |
| Повторна передача | Хто запустив, причина, результат. |
| Скасування | Хто скасував, причина. |
24. Acceptance Criteria
24.1. Інтеграція
| № | Критерій | Очікуваний результат |
|---|---|---|
| AC-1 | Адміністратор створює інтеграцію ANT-Logistics. | Інтеграція зберігається в системі. |
| AC-2 | Адміністратор перевіряє підключення. | Система повертає успішний або помилковий статус. |
| AC-3 | API key неправильний. | Система показує AuthError і не передає заявки. |
24.2. Заявки
| № | Критерій | Очікуваний результат |
|---|---|---|
| AC-4 | K2 ERP створює заявку на доставку. | Python-сервіс створює запис зі статусом PENDING_SEND. |
| AC-5 | Заявка проходить валідацію. | Вона додається в чергу передачі. |
| AC-6 | Заявка передана в ANT-Logistics. | Зберігається ant_task_id. |
| AC-7 | Повторний запит має той самий idempotency_key. | Друга заявка не створюється. |
24.3. Маршрути
| № | Критерій | Очікуваний результат |
|---|---|---|
| AC-8 | ANT-Logistics сформувала маршрут. | Python-сервіс отримує маршрут і зберігає його в K2 ERP. |
| AC-9 | Маршрут має точки доставки. | В K2 ERP зберігається порядок точок. |
| AC-10 | Маршрут призначений водію. | У K2 ERP відображається водій та автомобіль. |
24.4. Статуси
| № | Критерій | Очікуваний результат |
|---|---|---|
| AC-11 | Замовлення доставлено. | Статус у K2 ERP змінюється на DELIVERED. |
| AC-12 | Замовлення не доставлено. | Статус підсвічується червоним. |
| AC-13 | Замовлення частково доставлено. | Статус підсвічується помаранчевим. |
| AC-14 | API тимчасово недоступне. | Заявка переходить у NEEDS_RETRY. |
24.5. Dashboard
| № | Критерій | Очікуваний результат |
|---|---|---|
| AC-15 | Логіст відкриває dashboard. | Він бачить заявки, маршрути, статуси, проблеми та помилки. |
| AC-16 | Є недоставлені заявки. | Вони підсвічуються червоним. |
| AC-17 | Є заявки без координат. | Вони підсвічуються жовтим. |
| AC-18 | Є заявки, що потребують повтору. | Вони підсвічуються помаранчевим. |
25. MVP
До MVP входить:
- створення інтеграції ANT-Logistics;
- перевірка підключення;
- передача торгових точок;
- передача заявок на доставку;
- передача складів;
- передача автомобілів;
- передача водіїв;
- збереження ANT task ID;
- синхронізація маршрутів;
- синхронізація статусів доставки;
- дедублікація;
- retry-механізм;
- журнал подій;
- dashboard API;
- базові unit-тести;
- mock ANT API для інтеграційних тестів.
До MVP не входить:
- повна підтримка всіх методів ANT-Logistics;
- складна GPS-аналітика;
- власний модуль оптимізації маршрутів;
- заміна ANT-Logistics власним TMS;
- повна підтримка всіх сценаріїв мобільної торгівлі;
- автоматичне геокодування без перевірки якості адрес;
- складний UI логіста, якщо dashboard API достатньо для першого етапу.
26. Етапи реалізації
Етап 1. Аналіз API ANT-Logistics
- отримати API v2-документацію;
- створити API key;
- перевірити авторизацію;
- перевірити тестові запити;
- визначити методи для точок;
- визначити методи для заявок;
- визначити методи для маршрутів;
- визначити методи для статусів;
- визначити ліміти API.
Етап 2. Базовий Python-сервіс
- створити FastAPI-проєкт;
- налаштувати PostgreSQL;
- створити моделі інтеграції, точок, заявок, маршрутів, подій;
- налаштувати Alembic;
- реалізувати healthcheck.
Етап 3. ANT-Logistics Client
- реалізувати авторизацію;
- реалізувати check_connection;
- реалізувати create_or_update_point;
- реалізувати create_delivery_task;
- реалізувати cancel_delivery_task;
- реалізувати get_routes;
- реалізувати get_task_status;
- реалізувати обробку помилок.
Етап 4. Заявки та валідація
- реалізувати створення заявки;
- реалізувати мапінг K2 ERP → ANT;
- реалізувати валідацію;
- реалізувати hash заявки;
- реалізувати дедублікацію.
Етап 5. Черга та статуси
- реалізувати чергу передачі;
- реалізувати worker відправки;
- реалізувати worker синхронізації статусів;
- реалізувати worker синхронізації маршрутів;
- реалізувати retry.
Етап 6. Dashboard та аудит
- реалізувати dashboard API;
- реалізувати список проблемних доставок;
- реалізувати фільтри;
- реалізувати експорт, якщо потрібно.
Етап 7. Production hardening
- додати rate limiting;
- додати моніторинг;
- додати alerting;
- додати dead letter queue;
- додати резервне копіювання;
- додати безпечне зберігання секретів.
27. Ризики
| Ризик | Опис | Як зменшити |
|---|---|---|
| Немає доступу до API v2 | Без API-доступу інтеграція неможлива. | Отримати доступ і тестовий ключ до старту. |
| Неправильні адреси | Маршрути можуть будуватись некоректно. | Додати геокодування та ручну перевірку. |
| Дублювання заявок | Повторний запит може створити дубль доставки. | Idempotency key і ant_task_id. |
| Зміна заявки після планування | Може зламати маршрут. | Обмежити редагування після PLANNED. |
| Невідомі статуси ANT | API може повернути статус без мапінгу. | Таблиця status_mapping і статус UNKNOWN. |
| API недоступне | Заявки не передаються. | Черга, retry, dashboard помилок. |
| Відсутність координат | Маршрутизація може бути неточною. | Валідація координат і список проблемних точок. |
| GPS-дані неповні | Неможливо оцінити фактичний маршрут. | Робити GPS-синхронізацію опційною. |
28. Відкриті питання
- Яка версія API використовується: v1 чи v2?
- Чи є доступ до тестового акаунта?
- Які саме методи API доступні у вашому тарифі?
- Чи потрібно передавати торгові точки з K2 ERP?
- Чи потрібно передавати автомобілі та водіїв?
- Чи потрібно передавати товари або тільки вагу/об'єм?
- Чи потрібна автоматична оптимізація маршрутів або тільки передача заявок?
- Чи потрібно отримувати маршрути назад у K2 ERP?
- Чи потрібно отримувати фактичний GPS-трек?
- Чи потрібно передавати післяплату?
- Чи потрібно передавати часові вікна клієнтів?
- Чи потрібно підтримувати скасування заявки після планування?
- Як обробляти часткову доставку?
- Чи потрібен окремий dashboard у K2 ERP?
- Як часто синхронізувати статуси?
- Чи потрібні push-сповіщення логісту або менеджеру?
29. Джерела
- Офіційний сайт ANT-Logistics / Мурашина логістика.
- Сторінка API ANT-Logistics.
- Довідковий центр API v2 ANT-Logistics.
- Сторінка інтеграцій ANT-Logistics.
- Документація API v2 у кабінеті ANT-Logistics.
- Мобільний додаток Мурашина логістика для водіїв.