fix: read parent_id field from Evotor API and move VK products between albums on group change

- catalog.py: include parent_id as fallback for group_evotor_id (Evotor API returns parent_id instead of group/parentUuid)
- vk_sync.py: on product update, detect album change and call market.removeFromAlbum + market.addToAlbum to move product to the correct album

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
mguschin
2026-05-12 21:30:01 +03:00
parent 7b4f52b005
commit 83edac4200
2 changed files with 32 additions and 11 deletions

View File

@@ -8,11 +8,11 @@ Beat schedule entry (set in celery_app.py):
import logging
from datetime import datetime, timezone
import httpx
from celery import shared_task
from web.config import settings
from web.database import SessionLocal
import web.lib.api_logger as api_logger
from web.models.connections import CachedGroup, CachedProduct, CachedStore, EvotorConnection, SyncConfig, SyncFilter
logger = logging.getLogger(__name__)
@@ -34,18 +34,18 @@ def _now() -> datetime:
# ── per-user helpers ──────────────────────────────────────────────────────────
def _fetch_stores(token: str) -> list[dict]:
r = httpx.get(f"{EVO_API}/stores", headers=_headers(token), timeout=15)
def _fetch_stores(token: str, user_id: int | None = None) -> list[dict]:
r = api_logger.get(f"{EVO_API}/stores", user_id=user_id, headers=_headers(token), timeout=15)
r.raise_for_status()
data = r.json()
return data.get("items", data) if isinstance(data, dict) else data
def _fetch_groups(token: str, store_id: str) -> list[dict] | None:
def _fetch_groups(token: str, store_id: str, user_id: int | None = None) -> list[dict] | None:
"""Returns None if the store is not accessible (402/403), list otherwise."""
r = httpx.get(
r = api_logger.get(
f"{EVO_API}/stores/{store_id}/product-groups",
headers=_headers(token), timeout=15,
user_id=user_id, headers=_headers(token), timeout=15,
)
if r.status_code in (402, 403):
return None
@@ -54,11 +54,11 @@ def _fetch_groups(token: str, store_id: str) -> list[dict] | None:
return data.get("items", data) if isinstance(data, dict) else data
def _fetch_products(token: str, store_id: str) -> list[dict] | None:
def _fetch_products(token: str, store_id: str, user_id: int | None = None) -> list[dict] | None:
"""Returns None if the store is not accessible (402/403), list otherwise."""
r = httpx.get(
r = api_logger.get(
f"{EVO_API}/stores/{store_id}/products",
headers=_headers(token), timeout=30,
user_id=user_id, headers=_headers(token), timeout=30,
)
if r.status_code in (402, 403):
return None
@@ -158,7 +158,7 @@ def _sync_user(db, user_id: int, token: str) -> None:
row = db.query(CachedProduct).filter_by(user_id=user_id, evotor_id=evo_id).first()
if row:
row.store_evotor_id = store_evo_id
row.group_evotor_id = p.get("group") or p.get("parentUuid")
row.group_evotor_id = p.get("group") or p.get("parentUuid") or p.get("parent_id")
row.name = p.get("name", "")
row.price = float(price) if price is not None else None
row.quantity = float(quantity) if quantity is not None else None
@@ -171,7 +171,7 @@ def _sync_user(db, user_id: int, token: str) -> None:
user_id=user_id,
evotor_id=evo_id,
store_evotor_id=store_evo_id,
group_evotor_id=p.get("group") or p.get("parentUuid"),
group_evotor_id=p.get("group") or p.get("parentUuid") or p.get("parent_id"),
name=p.get("name", ""),
price=float(price) if price is not None else None,
quantity=float(quantity) if quantity is not None else None,