| Комплектується
|
PROCESSING
|
-
|
ConnectionError
|
API Horoshop недоступне.; характеристика
k2_product_id=product.id,
},
external_order_id=external_order_id,
API-запити виконуються до шлюзу:
== 2.; Область сфера застосування ==
"horoshop_status": order_payload.get("status"),
=== 12.2.; Основні компоненти Python-сервісу ===
"customer_name": order_payload.get("customer", {}).get("name"),
32.; Ризики
|
-
|
old_status
|
varchar
|
}
|
; Очікуваний результат
7.1.; Менеджер товарного каталогу
"status": horoshop_status,
entity_id=hs_order.id,
db=db,
!; # Чи потрібно імпортувати категорії з Horoshop?; | style="background:#eeeeee;" | Сірий
|-
| Помилка
| ERROR
| Помилка імпорту або актуалізація.; | style="background:#ef9a9a;" | Червоний
|}
horoshop_order_repository.create(
{| class="wikitable"
response = await client.post(url, json=request_payload)
"amount": 12999.00
except Exception as exc:
HOROSHOP_API_PASSWORD=********
|-
| Нове
| NEW
| Замовлення отримано з Horoshop.; |}
<syntaxhighlight lang="python">
'''істотно:''' приклад авторизації є собою архітектурним.; | style="background:#bbdefb;" | Блакитний
|-
| Синхронізовано
| SYNCED
| Товар успішно передано або оновлено.; | Нові замовлення, очікування оплати.; |-
| Недоступність API
| Синхронізація зупинена.; |-
| payment_status
| varchar
| Статус оплати.; |-
| Price Sync Worker
| Передає ціни.; "status": "new",
23.5.; актуалізація статусу замовлення
29.6. Dashboard
async def sync_product_to_horoshop(product_id: str, db: "Session") -> None:
entity_id=hs_product.id,
8.; Напрями синхронізації
|
; Поле
{| class="wikitable"
== 30. MVP ==
<div style="border-left: 6px solid #c62828; background: #ffebee; padding: 12px 16px; margin: 16px 0;">
|-
| id
| uuid
| ID запису.; |-
| Attribute Mapper
| Мапить характеристики.; |-
| Ціни
| актуалізація базових, акційних, роздрібних цін.; Якщо товар не знайдено — статус NEEDS_REVIEW.; !; )
* реалізувати dashboard API;
* реалізувати список проблемних товарів;
* реалізувати список проблемних замовлень;
* реалізувати список помилок API;
* реалізувати експорт, якщо потрібно.; |-
| Зміна ціни
| Стара ціна, нова ціна, дата.; | style="background:#bbdefb;" | Блакитний
|-
| Очікує оплати
| WAITING_PAYMENT
| Замовлення очікує оплату.; class HoroshopClient:
HOROSHOP_BASE_URL=https://example.com/api/
<syntaxhighlight lang="json">
{| class="wikitable"
!; |-
| Product Image
| Фото товару.; Як зменшити
=== Етап 3.; Horoshop Client ===
Python-сервіс повинен:
== 34.; Джерела ==
"price": 12999.00,
"quantity": available_stock,
payload={
"customer_email": order_payload.get("customer", {}).get("email"),
!; |-
| AC-14
| Замовлення імпортовано.; Поле
!; |}
== 5.; Основні бізнес-сценарії ==
url = f"{self.base_url}/{function.strip('/')}/"
"https://example.com/images/sku-001-1.jpg",
horoshop_status = status_mapping_repository.map_k2_to_horoshop(
== 7. User Story ==
"address": null
def create_or_update_category(self, payload: dict) -> "CategoryResponse":
"name": "Смартфон Example X 128GB",
== 31.; Етапи реалізації ==
K2 ERP / Dashboard / Менеджери
}
== 13. Horoshop API Client ==
=== Етап 6.; Замовлення ===
3.; !; Джерело істини
=== 29.5.; Статуси та ТТН ===
except Exception as exc:
data={
* SKU заповнений;
* назва заповнена;
* характеристика заповнений;
* категорія визначена;
* категорія Horoshop замаплена;
* ціна більша за 0;
* залишок не від'ємний;
* фото доступні;
* головне фото визначене;
* характеристики заповнені;
* бренд заповнений, якщо потрібен;
* штрихкод валідний, якщо застосовується;
* товар не дублюється за SKU;
* товар не дублюється за external_product_id;
* текст опису не містить небезпечного HTML;
* активність товару відповідає правилам публікації.; |-
| Order
| Замовлення.; |-
| AC-2
| Адміністратор перевіряє підключення.;=== 15.3.; Синхронізація категорій ===
{| class="wikitable"
|-
| id
| uuid
| ID інтеграції.; | Manual review.; |-
| raw_response
| jsonb
| Відповідь API.; |-
| Доставка
| Передача служби доставки, адреси, ТТН.; №
available_stock = stock_engine.calculate_available_stock(
{| class="wikitable"
== 28.; Логування та аудит ==
'''істотно:''' назви методів Python-клієнта є собою внутрішньою абстракцією.; Стан
<div style="border-left: 6px solid #1565c0; background: #e3f2fd; padding: 12px 16px; margin: 16px 0;">
=== Етап 8.; Dashboard та аудит ===
!;
- Офіційна документація Horoshop API.; |-
|
актуалізація статусів замовлень
|
Високий
|
Впливає на клієнтський досвід.; характеристика
)
Етап 5.; Ціни та залишки
pass
def update_product_price(self, product_id: str, payload: dict) -> "PriceResponse":
pass
HOROSHOP_LANGUAGE=ua
None = None) -> dict:
"category_id": "phones",
client = horoshop_client_factory.create(integration)
|
K2 ERP
|
істотно для комерційного контролю.;
- реалізувати Product Mapper;
- реалізувати Category Mapper;
- реалізувати Attribute Mapper;
- реалізувати валідацію;
- реалізувати Product Sync Worker.; | платформа передає нову ціну в Horoshop.; Критерій
Python Horoshop Integration Service
def create_or_update_product(self, payload: dict) -> "ProductResponse":
{| class="wikitable"
Retry дозволений для:
"order_number": "000123",
HOROSHOP_RETRY_COUNT=3
!; | style="background:#fff9c4;" | Жовтий
|-
| Потребує виправлення
| NEEDS_CORRECTION
| Не вистачає категорії, ціни, фото, опису або характеристик.; |-
| ValidationError
| Некоректний товар або замовлення.; |-
| product_hash
| Hash назви, опису, ціни, залишку, характеристик.; |-
| payload
| jsonb
| Технічні інформаційні дані.; def get_customers(self, filters: dict) -> "CustomerListResponse":
v
* отримати доступ до API;
* створити API login/password в адмінпанелі;
* перевірити base_url;
* перевірити тестовий запит;
* визначити методи товарів;
* визначити методи замовлень;
* визначити методи статусів;
* визначити методи цін і залишків;
* визначити обмеження API.; payload=response,
=== 7.4.; Керівник ===
)
</div>
],
=== Етап 4.; Товари ===
"order_date": "2026-05-07T12:10:00+03:00",
response = await client.call_api(
!; |-
| barcode
| Штрихкод.; | Заблокувати синхронізацію ціни.; №
)
Horoshop є собою джерелом замовлень, які створюють покупці на сайті.; |-
| API Event
| Технічна подія інтеграції.; | Перевести в ручну перевірку.; |-
| sync_statuses_enabled
| boolean
| актуалізація статусів.; |}
== 3.; Основні функціональні можливості інтеграції ==
if data.get("status") in ["error", "failed"]:
!; замовник
K2 ERP є собою головним джерелом операційного статусу.; |}
</div>
!; | Передати менеджеру каталогу.; Імпорт у K2 ERP
horoshop_product_repository.update_stock_sync_result(
== 1.; Мета ==
=== 22.1. horoshop_integrations ===
if not validation_result.is_valid:
"is_active": true
db=db,
horoshop_order_repository.create_error_record(
|-
| API Layer
| REST API для команд із K2 ERP.;</div>
== 6.; Основні сутності ==
<div style="border-left: 6px solid #c62828; background: #ffebee; padding: 12px 16px; margin: 16px 0;">
{| class="wikitable"
3.; |-
| Некоректний товар
| Товар не публікується.; | style="background:#ffcc80;" | Потрібна дія
|-
| Помилки API
| Технічні помилки інтеграції.; Код
hs_product.horoshop_product_id = response.get("product_id") or hs_product.horoshop_product_id
POST /api/v1/horoshop/products/sync-batch
def get_orders(self, filters: dict) -> "OrderListResponse":
щоб покупці не замовляли товар, якого немає.; |-
| id
| uuid
| ID замовлення.; | K2 ERP / служби доставки
| Нова пошта, Укрпошта тощо.; Ключ
)
{| class="wikitable"
"comment": "Зателефонувати перед відправкою",
__TOC__
!; |-
| Залишки
| актуалізація доступної кількості.; if not hs_order:
{| class="wikitable"
== 17.; Приклад замовлення з Horoshop ==
{| class="wikitable"
|-
| Horoshop Integration
| конфігурація підключення до конкретного сайту.; |-
| ТТН / ЕН
| K2 ERP → Horoshop
| K2 ERP / доставка
| Інформування покупця про доставку.; Код
)
3.; |-
| AC-7
| Товар успішно передано.; !; # Чи є собою модифікації / варіанти товарів?; |-
| Статуси
| актуалізація статусів замовлень на сайті.; # Як часто оновлювати залишки?; |-
| Category
| Категорія товарів.; Тип
# Чи K2 ERP є собою головним джерелом товарів?; |-
| Order Import Worker
| Імпортує замовлення.; * додати rate limiting;
* додати retry policy;
* додати dead letter queue;
* додати alerting;
* додати моніторинг;
* додати резервне копіювання;
* додати безпечне зберігання secret-ів.; |-
| quantity
| numeric
| Кількість.; !; Критерій
"images": [
|-
| AC-4
| Товар має всі обов'язкові поля.; Заборонено зберігати їх у коді, Git, frontend-змінних або відкритих логах.; | style="background:#c8e6c9;" | Норма
|-
| Помилки товарів
| Товари з помилками валідації або API.; характеристика
raise HoroshopApiError(str(data))
=== 23.3.; Імпорт замовлень ===
!; api_login: str
"email": "client@example.com"
це Python-клас або пакет, який інкапсулює роботу з API конкретного сайту Horoshop виступає ключовою рисою Horoshop API Client.; Де застосовується
db=db,
=== 13.3.; Основні методи клієнта ===
pass
=== 26.3.; Проблемні товари ===
<syntaxhighlight lang="json">
"old_price": 13999.00,
=== 22.7. horoshop_events ===
щоб контролювати помилки, продажі та реалізація, синхронізацію товарів і проблемні замовлення.; !; | style="background:#c8e6c9;" | Зелений
|-
| Приховано
| HIDDEN
| Товар прихований на сайті.; Значення
=== 29.2.; Товари ===
product = product_repository.get_by_id(db, product_id)
"warranty": "12 місяців"
POST /api/v1/horoshop/integrations
!;=== 15.1.; Створення інтеграції ===
if existing:
payload=response,
{| class="wikitable"
6.; Напрям
=== 15.11. Dashboard ===
2.; Поле
"delivery_service": order_payload.get("delivery", {}).get("service"),
external_order_id = str(order_payload ["id"])
"type": "online_card",
!; №
</div>
!; Колір
v
!; |-
| base_url
| varchar
| URL API.; self.api_login = api_login
інтеграційні функціональні можливості призначена для:
!; Поле
raise HoroshopApiError(response.text)
<pre>
external_order_id=external_order_id,
5.;=== 23.1.; Базовий Horoshop Client ===
13.2.; Загальні принципи
payload = {
; характеристика
15.; API Python-сервісу
</syntaxhighlight>
"k2_order_id": k2_order.id,
errors=validation_result.errors,
return
POST /api/v1/horoshop/prices/sync
Це відповідає офіційній документації Horoshop API, де вказано, що шлюз має формат `http(s)://<DOMAIN>/api/`, а функції передаються через адресний рядок.; | K2 ERP
| Потрібні для фільтрів і SEO.; з цієї причини для кожного сайту потрібно зберігати власний base_url, логін, пароль, статус інтеграції, правила синхронізації та технічний журнал.; |-
| Order Mapper
| Перетворює замовлення Horoshop у формат K2 ERP.; |-
| order_id
| uuid
| Замовлення.; |-
| Customer
| Покупець.; event_type="HOROSHOP_PRODUCT_SYNCED",
!; Створюється задача Stock Sync.; характеристика
"external_order_id": "HS-ORDER-000123",
=== 21.4.; Пріоритети задач ===
{| class="wikitable"
|-
| Категорії
| K2 ERP → Horoshop або Horoshop → K2 ERP
| Залежить від проєкту
| Єдина структура каталогу.; | K2 ERP / WMS
| Критичний бізнес-процес.; * timeout;
* HTTP 429;
* HTTP 500;
* HTTP 502;
* HTTP 503;
* HTTP 504;
* тимчасової недоступності API;
* тимчасової помилки імпорту замовлень;
* тимчасової помилки актуалізація ціни;
* тимчасової помилки актуалізація залишку;
* тимчасової помилки актуалізація статусу.; |-
| payment_type
| varchar
| Тип оплати.; Як адміністратор,
pass
* створення нового клієнта в K2 ERP на основі замовлення Horoshop;
* пошук клієнта за телефоном;
* пошук клієнта за email;
* актуалізація ПІБ;
* актуалізація адреси доставки;
* історію замовлень клієнта;
* мапінг customer_id Horoshop ↔ customer_id K2 ERP.; Він повинен потрапляти у статус NEEDS_CORRECTION.; |
| 5.; Тип
hs_product.raw_response = response
<div style="border-left: 6px solid #f57c00; background: #fff3e0; padding: 12px 16px; margin: 16px 0;">
k2_product_id=product.id,
=== 26.4.; Проблемні замовлення ===
'''Критично істотно:''' товар без SKU, категорії, ціни або головного фото не повинен автономно передаватися в Horoshop.; | style="background:#ef9a9a;" | Червоний
|}
!; |-
| event_type
| varchar
| Тип події.; Враховуються резерви та страховий залишок.; # Чи потрібно підтримувати кілька сайтів Horoshop?; | style="background:#c8e6c9;" | Норма
|-
| Оновлено залишків
| Кількість успішних оновлень залишків.; :contentReference [oaicite:2]{index=2}
я хочу бачити dashboard інтеграції,
return
=== 20.2.; Дедублікація замовлень ===
"customer_phone": order_payload.get("customer", {}).get("phone"),
[[Категорія:CRM]]
K2 ERP є собою головним джерелом товарного каталогу.; SKU
</syntaxhighlight>
</syntaxhighlight>
hs_product.status = "SYNCING"
<div style="border-left: 6px solid #c62828; background: #ffebee; padding: 12px 16px; margin: 16px 0;">
retry_backoff_seconds: int = 5
4.;== 12.; технічна архітектура рішення для бізнесу ==
{
!; from pydantic_settings import BaseSettings
"description": "характеристика товару для сайту.",
product_status_service.set_status(
я хочу, щоб залишки автономно оновлювалися на сайті,
"name": "Іван Петренко",
[[Категорія:K2 ERP]]
|-
| AuthError
| Невірний API login або password.; |-
| Audit Logger
| Запити, відповіді, помилки, статуси.;<pre>
* створити FastAPI-проєкт;
* налаштувати PostgreSQL;
* створити моделі інтеграцій, товарів, замовлень, мапінгів, подій;
* налаштувати Alembic;
* реалізувати healthcheck.; |-
| Product Mapper
| Перетворює товар K2 ERP у формат Horoshop.; |-
| Horoshop Product
| Товар на сайті Horoshop.; Компонент
!; |-
| Категорії
| Синхронізація структури каталогу.; Сутність
db.commit()
try:
"status": "paid",
HOROSHOP_TIMEOUT_SECONDS=30
!; |-
| Товари
| K2 ERP → Horoshop
| K2 ERP
| Публікація каталогу.; |-
| style="background:#fff9c4;" | Жовтий
| #fff9c4
| Очікування дії або оплати.; # Які типи оплат і доставок потрібно підтримати?; | NEEDS_CORRECTION / NEEDS_REVIEW.; "external_customer_id": "HS-CUSTOMER-001",
payload = horoshop_product_mapper.to_payload(product)
!; |-
| api_password_encrypted
| text
| Зашифрований API password.; Worker регулярно запитує нові замовлення Horoshop.; |}
!; | Замовлення потрапляє в ручну перевірку.; POST /api/v1/horoshop/orders/{order_id}/update-status
- інтернет-магазинів на Horoshop;
- компаній, які ведуть обліковий облік у K2 ERP;
- компаній, які мають CRM і хочуть імпортувати замовлення з сайту;
- складів, які мають оновлювати залишки на сайті;
- менеджерів продажів;
- e-commerce відділів;
- компаній із кількома інтернет-магазинами;
- компаній, які продають через сайт і маркетплейси одночасно.; |-
|
sync_orders_enabled
|
boolean
|
style="background:#c8e6c9;" | Зелений
|
| Потребує перевірки
|
NEEDS_REVIEW
|
-
|
is_active
|
boolean
|
K2 ERP
|
-
|
Синхронізація товарів
|
Середній
|
платформа передає новий залишок.; | style="background:#fff9c4;" | Увага
|
| Імпортовано замовлень
|
}
def check_connection(self) -> "ConnectionStatus":
request_payload ["password"] = self.api_password
retry_count: int = 3
|
|
1.; # Які статуси Horoshop потрібно замапити?; },
- повна супровід всіх API-методів Horoshop;
- складна SEO-оптимізація товарів;
- автоматичне створення маркетингових акцій;
- складний UI керування каталогом;
- інтеграційні функціональні можливості з усіма маркетплейсами;
- автоматичне виправлення товарних даних;
- ML-мапінг категорій і характеристик.; |-
|
name
|
varchar
|
Назва інтеграції.; Значення
20.; Дедублікація
== 23.; Приклад Python-логіки ==
class HoroshopApiError(Exception):
payload=payload,
horoshop_product_repository.set_sync_error(
)
<pre>
=== 7.2.; складський облік ===
{| class="wikitable"
"memory": "128GB",
</syntaxhighlight>
<pre>
response = await client.call_api(
|-
| Імпорт замовлень
| Критичний
| Впливає на продажі та реалізація.; | Horoshop
| Замовлення створюються покупцями на сайті.; |-
| direction
| varchar
| IMPORT або EXPORT.; | Воно імпортується в K2 ERP.; Очікуваний результат
{
async def import_horoshop_orders(db: "Session") -> None:
11.; Єдина логіка кольорівПеред передачею товару в Horoshop платформа повинна перевірити:
платформа повинна підтримувати:
15.10.; Передача ТТН / ЕН"amount": 12999.00
POST /api/v1/horoshop/integrations/{integration_id}/check-connection
db=db,
if response.status_code >= 400:
15.7.; актуалізація залишків22.4. horoshop_order_items"raw_payload": order_payload,
"service": "nova_poshta",
Python-сервіс повинен:
</syntaxhighlight>
| Horoshop / K2 ERP
|
Залежить від бізнес-логіки.; hs_product = horoshop_product_repository.get_or_create(
"sku": product.sku,
|
-
|
Зміна API
|
Методи або поля можуть змінитись.; HOROSHOP_RETRY_BACKOFF_SECONDS=5
- реалізувати call_api;
- реалізувати check_connection;
- реалізувати get_orders;
- реалізувати update_order_status;
- реалізувати create_or_update_product;
- реалізувати update_price;
- реалізувати update_stock;
- реалізувати обробку помилок.; | style="background:#ffcc80;" | Помаранчевий
|
| Готовий до синхронізації
|
READY_TO_SYNC
|
Товар можна передавати.; Тип
5.; |-
|
order_number
|
-
|
Дублювання замовлень
|
Передати менеджеру каталогу.; |}
23.4.; актуалізація залишку
}
response = await client.call_api(
Для реалізації задачі необхідно отримати:
def call_api(self, function: str, payload: dict | None = None) -> dict:
def authenticate(self) -> "AuthResult":
|
| AC-1
|
API-запити, черги, обробка.; | style="background:#bbdefb;" | Блакитний
|
| Виконано
|
COMPLETED
|
style="background:#c8e6c9;" | Норма
|
| Нові замовлення
|
Нові замовлення з Horoshop.; HTML
|
; Статус K2 ERP
22.5. horoshop_category_mappings
"comment": order.manager_comment,
v
15.8.; Імпорт замовлень
5.2.; актуалізація цінpass
Перед створенням замовлення в K2 ERP платформа повинна перевірити:
Інтернет-магазин Horoshop
; KPI
=== 15.5.; Масова синхронізація товарів ===
payload=payload,
== 19.; Валідація замовлень ==
<pre>
Метою задачі є собою створення Python-сервісу для інтеграції K2 ERP / CRM / WMS з інтернет-магазином на платформі Horoshop.; Об'єкт
Як менеджер товарного каталогу,
!; |}
{| class="wikitable"
integration = horoshop_integration_repository.get_active(db)
{| class="wikitable"
db=db,
{| class="wikitable"
|-
| id
| uuid
| ID мапінгу.; |-
| Price Engine
| Формує ціни для сайту.; До MVP не входить:
* реалізувати мапінг статусів;
* реалізувати Status Export Worker;
* реалізувати передачу ТТН;
* реалізувати журнал статусів.; Назва
<syntaxhighlight lang="python">
{| class="wikitable"
"status": "new"
!; def get_order(self, order_id: str) -> "OrderResponse":
"sku": "SKU-001",
def update_order_status(self, order_id: str, payload: dict) -> "OrderStatusResponse":
=== 7.3.; Менеджер продажів ===
!; entity_type="product",
"total_amount": 12999.00,
* отримати товар із K2 ERP;
* перевірити обов'язкові поля;
* визначити категорію;
* підготувати назву;
* підготувати характеристика;
* підготувати характеристики;
* підготувати фото;
* підготувати ціну;
* підготувати залишок;
* створити або оновити товар у Horoshop;
* зберегти external_product_id;
* записати результат у журнал.; existing = horoshop_order_repository.get_by_external_id(
!;<pre>
class HoroshopSettings(BaseSettings):
new_status="SYNCED",
pass
!; * Центр допомоги Horoshop.; {
<pre>
audit_logger.log(
verify_ssl: bool = True
|-
| sku
| ключовий артикул.;== 21.; Черги синхронізації ==
{| class="wikitable"
client = horoshop_client_factory.create(integration)
function="orders/get/",
for order_payload in orders:
=== 13.1.; Призначення ===
Як комірник або WMS,
!; |-
| Stock
| Залишок товару.; |-
| style="background:#eeeeee;" | Сірий
| #eeeeee
| Чернетка, приховано, скасовано або архів.; Статус
"product_id": "K2-PRODUCT-000123",
10.; Статуси замовлень
24.; Обробка помилок
)
== 18.; Валідація товарів ==
orders = response.get("orders", [])
pass
)
=== 21.3.; Логіка імпорту замовлень ===
!; |-
| style="background:#ef9a9a;" | Червоний
| #ef9a9a
| Критична помилка.; db=db,
entity_type="order",
</pre>
* отримати статус замовлення з K2 ERP;
* замапити його у статус Horoshop;
* передати статус у Horoshop;
* передати ТТН / ЕН, якщо є собою;
* передати коментар менеджера, якщо підтримується;
* записати подію в журнал.; |-
| Статуси замовлень
| K2 ERP → Horoshop
| K2 ERP
| Покупець бачить актуальний статус.; |-
| status
| varchar
| Статус K2 ERP.; |-
| актуалізація залишків
| Критичний
| Захищає від продажу відсутнього товару.; "name": "Смартфон Example X 128GB",
"price": 12999.00,
try:
|-
| AC-18
| Керівник відкриває dashboard.; |-
| external_order_id
| varchar
| ID замовлення Horoshop.; |-
| DuplicateOrderError
| Замовлення вже імпортовано.; |-
| Клієнти
| Імпорт або актуалізація клієнтів.; |-
| sync_stocks_enabled
| boolean
| Синхронізація залишків.; Показник
hs_product.status = "SYNCED"
product = product_repository.get_by_id(db, product_id)
<pre>
timeout_seconds: int = 30
def __init__(self, base_url: str, api_login: str, api_password: str, timeout_seconds: int = 30):
!; |-
| Клієнти
| Horoshop → K2 ERP
| Horoshop
| Створення клієнтів із замовлень.; |-
| last_synced_price
| numeric
| Остання передана ціна.; Помилка
"sku": "SKU-001",
Коли ціна змінюється в K2 ERP, Python-сервіс повинен:
!; |-
| horoshop_product_id
| ID товару в Horoshop.; |-
| k2_product_id
| uuid
| ID товару K2 ERP.; |-
| Product
| Товар у K2 ERP.; | Вони підсвічуються жовтим.; |-
| актуалізація статусу
| Старий статус, новий статус.; |-
| AC-6
| Товар не має категорії.; | K2 ERP або Horoshop
| Визначається правилами проєкту.; |-
| style="background:#bbdefb;" | Блакитний
| #bbdefb
| операційна дія виконується.; |}
!; | Статус стає IMPORTED.; Поле
)
=== 22.6. horoshop_status_mappings ===
"customer": {
|-
| Перевірка підключення
| URL, результат, час, без пароля.;=== 21.2.; Логіка актуалізація залишків ===
db.commit()
db=db,
* регулярно отримувати нові замовлення;
* перевіряти, чи замовлення вже імпортоване;
* створювати замовлення в K2 ERP;
* створювати або оновлювати клієнта;
* зберігати товари замовлення;
* зберігати оплату;
* зберігати доставку;
* зберігати коментар покупця;
* резервувати товар;
* змінювати статус замовлення в Horoshop, якщо потрібно.; |-
| delivery_address
| text
| Адреса доставки.; |-
| Horoshop Client
| Python-клієнт для Horoshop API.; |-
| AC-19
| є собою помилки синхронізації.; |}
"payment": {
payload=order_payload,
щоб вони автономно з'являлися та оновлювалися на сайті Horoshop.; | Повернути існуюче замовлення.; | Unique constraint по external_order_id + site_id.; |-
| k2_category_id
| varchar
| Категорія K2 ERP.; | Статус стає SYNCED.; # Чи потрібно синхронізувати фото?; Якщо замовлення нове — створює його в K2 ERP.; Задача
=== 29.4.; Замовлення ===
!; |-
| CategoryMappingError
| Не знайдено категорію Horoshop.; Поле
!; | Маскування телефону/email.; | Вони підсвічуються помаранчевим.; | Dashboard, товари, замовлення.; |-
| idempotency_key
| Ключ повторної обробки.;=== Етап 2.; Базовий Python-сервіс ===
{| class="wikitable"
</pre>
!; Валідація, мапінг, черги, дедублікація
6.; |-
| Незамаплений статус
| Статус не передається.; Реальні назви функцій Horoshop API потрібно брати з актуальної документації конкретного магазину.; Дата
integration = horoshop_integration_repository.get_active(db)
!; | Зупинити інтеграцію, повідомити адміністратора.; |-
| Залишки
| K2 ERP/WMS → Horoshop
| K2 ERP / WMS
| Актуальна наявність.; api_password: str
!; характеристика
"https://example.com/images/sku-001-2.jpg"
|-
| Невірні API-доступи
| інтеграційні функціональні можливості не працюватиме.; WMS або K2 ERP змінює залишок.; | Check-connection і alert адміністратору.; | Таблиця status_mappings і ручна перевірка.; Пріоритет
{| class="wikitable"
payload=payload,
!; |-
| order_number
| varchar
| Номер замовлення.; |-
| price
| numeric
| Ціна.; # Чи потрібно передавати ТТН у Horoshop?; Результат зберігається.; |-
| customer_name
| varchar
| Покупець.; # Як часто оновлювати ціни?; |-
| Продаж відсутнього товару
| Залишки не оновились вчасно.; * створення інтеграції Horoshop;
* перевірка підключення;
* синхронізація категорій або мапінг категорій;
* синхронізація товарів;
* синхронізація цін;
* синхронізація залишків;
* імпорт замовлень;
* імпорт клієнтів із замовлень;
* актуалізація статусів замовлень;
* передача ТТН;
* дедублікація;
* retry-механізм;
* журнал подій;
* dashboard API;
* unit-тести;
* mock Horoshop client.; Тип
hs_product.status = "SYNC_ERROR"
=== 29.3.; Ціни та залишки ===
{| class="wikitable"
!; | Він не передається і показується менеджеру.; K2 ERP змінює товар.; Призначення
db=db,
"tracking_number": order.tracking_number,
!; |-
| AC-9
| У K2 ERP змінився залишок.; |-
| Створення клієнта
| Телефон/email у замаскованому вигляді.; Тип
Приклад `.env`:
hs_product.last_synced_stock = product.available_stock
!; Результат записується в журнал.; |-
| Status Export Worker
| Передає статуси назад у Horoshop.; |-
| product_hash
| varchar
| Hash даних товару.; |-
| ImageError
| Фото недоступне.; Резервує товар у K2 ERP.; # Чи потрібно синхронізувати декілька складів?; # Чи потрібно створювати категорії в Horoshop автономно?; |-
| Ціни
| K2 ERP → Horoshop
| K2 ERP
| Актуальні ціни на сайті.; # Чи потрібно синхронізувати акційні ціни?; |-
| Product Sync Worker
| Передає товари.; |-
| Dashboard API
| інформаційні дані для контролю інтеграції.; Дія
hs_product.error_message = str(exc)
Python-сервіс повинен:
{{DISPLAYTITLE:Технічне завдання: Інтеграція з Horoshop / Хорошоп для Python}}
async def sync_stock_to_horoshop(product_id: str, db: "Session") -> None:
K2 ERP / CRM / WMS
!; |-
| Attribute
| Характеристика товару.; | style="background:#c8e6c9;" | Зелений
|-
| Відправлено
| SHIPPED
| Замовлення передано в доставку.; |-
| k2_order_id
| uuid
| ID замовлення K2 ERP.; |-
| error_message
| text
| Остання помилка.; | style="background:#bbdefb;" | Блакитний
|-
| Синхронізується
| SYNCING
| Виконується API-запит до Horoshop.; |-
| UnknownStatusError
| Статус не замаплений.; |-
| Помилка API
| Код, текст, raw-відповідь без секретів.; |}
pass
== 4.; Передумови ==
* домен сайту Horoshop;
* API base URL;
* API login;
* API password;
* доступ до адмінпанелі Horoshop;
* список API-методів, які доступні на конкретному тарифі / сайті;
* актуальну документацію API;
* правила мапінгу категорій;
* правила мапінгу характеристик;
* список статусів замовлень Horoshop;
* список статусів замовлень K2 ERP;
* список типів оплат;
* список типів доставок;
* правила синхронізації цін;
* правила синхронізації залишків;
* правила обробки замовлень;
* правила передачі ТТН.; |-
| updated_at
| timestamp
| Дата актуалізація.; Очікуваний результат
7.; |-
| AC-3
| Login/password неправильні.; | style="background:#c8e6c9;" | Зелений
|-
| Опубліковано
| PUBLISHED
| Товар доступний на сайті.; характеристика
|-
| AC-15
| K2 ERP змінила статус замовлення.; |-
| Персональні інформаційні дані в логах
| Ризик витоку даних.;=== 5.5.; актуалізація статусу замовлення ===
!; |-
| style="background:#f3e5f5;" | Фіолетовий
| #f3e5f5
| Ручна перевірка або нестандартний сценарій.; |-
| Order Item
| Рядок замовлення.; # Чи потрібно приховувати товар при нульовому залишку?; |}
POST /api/v1/horoshop/orders/{order_id}/tracking-number
2.; Тип помилки
!; )
"horoshop_category_id": "h-category-001",
def update_product_stock(self, product_id: str, payload: dict) -> "StockResponse":
я хочу бачити журнал API-запитів,
"delivery": {
[[Категорія:E-commerce]]
|-
| SKU-001
| Смартфон Example X
| style="background:#ffcc80;" | Потребує виправлення
| Не замаплена категорія
| Заповнити мапінг
|-
| SKU-002
| Навушники Example Air
| style="background:#ef9a9a;" | Помилка
| Фото недоступне
| Перевірити URL фото
|-
| SKU-003
| Кавоварка Example
| style="background:#ffcc80;" | Потребує виправлення
| Немає ціни
| Заповнити ціну
|}
!; | інтеграційні функціональні можливості зберігається в системі.; | Заблокувати синхронізацію залишку.; Python-сервіс формує доступну кількість.; |-
| api_login_encrypted
| text
| Зашифрований API login.; Точну схему передачі login/password, token або session потрібно звірити з актуальною документацією Horoshop API для конкретного методу.; За потреби оновлює статус у Horoshop.; |-
| Retry
| Причина, кількість спроб, результат.; |}
!; |}
Сервіс повинен забезпечити:
щоб оперативно знаходити технічні помилки інтеграції.; Критерій
=== 15.9.; актуалізація статусу замовлення ===
sku=product.sku,
HOROSHOP_API_LOGIN=integration_user
self.timeout_seconds = timeout_seconds
25.; Retry-логіка
product_id=product_id,
POST /api/v1/horoshop/stocks/sync
)
я хочу вести товари в K2 ERP,
Retry заборонений для:
15.4.; Синхронізація товару
|
style="background:#c8e6c9;" | Зелений
|
| Скасовано
|
CANCELLED
|
-
|
AC-20
|
є собою товари без мапінгу.; !; Колір
|
Retry, queue, dashboard помилок.; Напрям
db.commit()
|
| id
|
uuid
|
style="background:#ef9a9a;" | Критично
|
| Оновлено цін
|
Заблокувати передачу товару.; | API error, sync error.; |-
|
last_synced_stock
|
numeric
|
-
|
Характеристики
|
-
|
Category Mapper
|
}
payload = {
language: str = "ua"
1.; |-
| sync_prices_enabled
| boolean
| Синхронізація цін.; |-
| external_order_id
| ID замовлення Horoshop.; !; Worker викликає Horoshop API.; | Високий пріоритет Stock Sync.; | style="background:#fff9c4;" | Жовтий
|-
| Імпортується
| IMPORTING
| Створюється замовлення в K2 ERP.; |}
http(s)://<DOMAIN>/api/<FUNCTION>/
синхронізації товарів забезпечується через '''Головна ідея:''' розробити Python-сервіс, який інтегрує K2 ERP / CRM / WMS з інтернет-магазином на платформі '''Horoshop / Хорошоп'''; додатково реалізовано категорій, характеристик, цін, залишків, клієнтів, замовлень, статусів, оплат, доставок і журналу помилок.; | style="background:#eeeeee;" | Сірий
|-
| Помилка синхронізації
| SYNC_ERROR
| API повернув помилку або товар не передано.; K2 ERP отримує статус.; | Draft, hidden, cancelled.; |}
!; Кожен товар, замовлення, замовник, зміна ціни, залишку, статусу та API-запит повинні мати внутрішній ID, external_id, журнал подій і захист від повторної обробки.; | Товар приховується або позначається як недоступний за правилом.; |-
| site_domain
| varchar
| Домен сайту.; Критерій
continue
!; |-
| customer_phone
| varchar
| Телефон.; |-
| Stock Sync Worker
| Передає залишки.; характеристика
validation_result = product_validator.validate(product)
</div>
request_payload = payload or {}
'''Технічний стек:''' Python 3.11+, FastAPI, PostgreSQL, SQLAlchemy, Alembic, httpx, Pydantic, Celery/RQ/APScheduler, Redis, Docker.; характеристика
До MVP входить:
except Exception as exc:
base_url: str
import httpx
k2_order = k2_order_service.create_from_horoshop(order_payload)
"phone": "+380671112233",
!; Тип
},
* отримати подію зміни ціни;
* визначити канали продажу;
* перевірити активність товару;
* застосувати правила округлення;
* застосувати правила акційної ціни;
* передати нову ціну в Horoshop;
* зберегти історію зміни.; характеристика
!; характеристика
stock=available_stock,
[[Категорія:WMS]]
event_type="HOROSHOP_ORDER_STATUS_EXPORTED",
!; |-
| is_active
| boolean
| Активність.; |-
| Синхронізація категорій
| Низький
| Довідник.; Призначення
v
=== 15.2.; Перевірка підключення ===
"attributes": {
|-
| Товари
| Створення та актуалізація товарів на Horoshop.; |-
| entity_id
| uuid
| ID сутності.; # Чи потрібно синхронізувати SEO-поля?; Колір
error=str(exc),
<syntaxhighlight lang="python">
!; |-
| sync_products_enabled
| boolean
| Синхронізація товарів.; },
}
== 26.; Dashboard керівника ==
function="orders/update_status/",
GET /api/v1/horoshop/dashboard?date_from=2026-05-01&date_to=2026-05-31
=== 29.1.; інтеграційні функціональні можливості ===
== 27.; Безпека ==
pass
try:
'''Критично істотно:''' інтеграційні функціональні можливості не повинна створювати дублікати товарів, клієнтів або замовлень.; Ризик
=== 5.1.; Передача товарів з K2 ERP у Horoshop ===
|-
| id
| uuid
| ID мапінгу.; №
error=str(exc),
|
| 2.; характеристика
=== Етап 9.; Production hardening ===
<pre>
"date_from": sync_state_repository.get_last_order_sync_date(db),
</pre>
)
|-
| style="background:#c8e6c9;" | Зелений
| #c8e6c9
| Успішно: синхронізовано, опубліковано, імпортовано, виконано.; * Технічні вимоги конкретного сайту Horoshop.; Очікуваний результат
"brand": "Example",
"warehouse": "Відділення №1",
POST /api/v1/horoshop/categories/sync
=== 23.2.; Синхронізація товару ===
<div style="border-left: 6px solid #6a1b9a; background: #f3e5f5; padding: 12px 16px; margin: 16px 0;">
function="catalog/update_stock/",
request_payload ["login"] = self.api_login
[[Категорія:Хорошоп]]
Horoshop API Client
{{SEO
|title=Технічне завдання: Інтеграція з Horoshop / Хорошоп для Python
|description=Технічне завдання на реалізацію Python-сервісу для інтеграції K2 ERP, CRM або WMS з Horoshop: товари, категорії, характеристики, ціни, залишки, замовлення, клієнти, статуси, оплати, доставки, API, фіди, помилки, dashboard та журналювання.
|keywords=Python, Horoshop, Хорошоп, Horoshop API, Хорошоп API, інтеграція інтернет-магазину, K2 ERP, CRM, WMS, товари, замовлення, ціни, залишки, FastAPI, ecommerce
}}
}
response=response,
</pre>
!; 4.; | style="background:#ffcc80;" | Помаранчевий
|-
| Підтверджено
| CONFIRMED
| Менеджер підтвердив замовлення.; Коментар
[[Категорія:Інтеграції]]
платформа повинна логувати:
"barcode": "4820000000000",
)
2.; |-
|
актуалізація цін
|
Високий
|
Впливає на маржу.; №
5.3.; актуалізація залишків
"quantity": 1,
}
26.2.; Приклад dashboard
|
| Чернетка
|
DRAFT
|
-
|
created_at
|
timestamp
|
Дата створення.; Ключ
|
-
|
sku
|
varchar
|
Артикул.; data = response.json()
|
|
3.; product_id=product.id,
|
; Тип
щоб обробляти всі продажі та реалізація в єдиній системі.; Критерій
12.1.; Загальна схема
Як менеджер продажів,
response = await client.call_api(
4.; Статус
|
; Очікуваний результат
29. Acceptance Criteria
warehouse_id=product.default_warehouse_id,
Як керівник,
"stock_quantity": 12,
integration = horoshop_integration_repository.get_active(db)
return data
1.; Критерій
db.commit()
== 33.; Відкриті питання ==
!; Створюється задача Product Sync.; Функції API викликаються через URL:
я хочу отримувати замовлення з Horoshop у K2 ERP,
=== 5.4.; Імпорт замовлень ===
'''Критично істотно:''' логін і пароль API Horoshop потрібно зберігати тільки у secret storage або в зашифрованому вигляді.; Коли змінюється залишок на складі, Python-сервіс повинен:
* реалізувати Price Engine;
* реалізувати Stock Engine;
* реалізувати чергу актуалізація;
* реалізувати історію змін.; |-
| k2_product_id
| ID товару в K2 ERP.; |-
| AC-17
| Статус не замаплений.; |-
| Delivery
| Доставка.; | style="background:#bbdefb;" | Блакитний
|-
| Імпортовано
| IMPORTED
| Замовлення створено в K2 ERP.; Перевіряє external_order_id.; | Вони підсвічуються червоним.; Що зберігати
k2_product_id=product.id,
{| class="wikitable"
!;[[Категорія:Технічні завдання]]
=== 26.1.; Основні KPI ===
5.6.; Обмін клієнтами
15.6.; актуалізація цін
Управлінський результат: менеджер і керівник повинні бачити, які товари синхронізовані з Horoshop, які мають помилки, які замовлення імпортовані, які статуси передані, які залишки не оновились, які товари не мають фото, категорії або характеристик.; * Сторінка Horoshop API.; Призначення
20.1.; Дедублікація товарів
POST /api/v1/horoshop/orders/import
],
)
"order_number": order_payload.get("number"),
|
|
|
|
|