from typing import List, Dict, Any, Optional from django.conf import settings from .client import RecommerceClient from .mappers import to_api_product, from_api_order from .exceptions import RecommerceError # Imports for typing only to avoid circular dependency issues at module level if possible # but for simplicity in this structure we'll import inside methods if needed or use 'Any' class RecommerceService: """ Высокоуровневый сервис для интеграции с Recommerce. Предоставляет методы для синхронизации товаров и заказов. """ def __init__(self, integration_instance): """ Args: integration_instance: Экземпляр модели RecommerceIntegration """ self.integration = integration_instance self.client = RecommerceClient( store_url=integration_instance.store_url, api_token=integration_instance.api_token ) def update_product(self, product: Any, fields: Optional[List[str]] = None) -> bool: """ Обновить товар в Recommerce. Args: product: Экземпляр Product fields: Список полей для обновления (например ['price', 'count']). Если None - обновляются все поля. Returns: bool: Успех операции """ # Получаем остаток, если нужно stock_count = None if fields is None or 'count' in fields: # Пытаемся получить остаток. # Логика получения остатка может зависеть от вашей системы inventory. # Здесь предполагаем, что у product есть метод или связь для получения общего остатка. # Для простоты используем первый попавшийся Stock или 0 # В реальном проекте тут должна быть логика выбора склада stock = product.stocks.first() stock_count = int(stock.quantity_free) if stock else 0 data = to_api_product(product, stock_count=stock_count, fields=fields) try: # Сначала пробуем обновить # SKU берем из data или продукта sku = data.get('sku', getattr(product, 'sku', str(product.id))) # Recommerce API: POST /catalog/products/{sku} для обновления self.client.update_product(sku, data) return True except RecommerceError as e: # Если 404 - товар не найден, можно попробовать создать? # В рамках "простой" интеграции - пока просто логируем или рейзим # Если нужно автоматическое создание: # if isinstance(e, RecommerceAPIError) and e.status_code == 404: # return self.create_product(product) raise e def create_product(self, product: Any) -> bool: """Создать товар в Recommerce""" # Для создания нужны все поля stock = product.stocks.first() stock_count = int(stock.quantity_free) if stock else 0 data = to_api_product(product, stock_count=stock_count, fields=None) self.client.create_product(data) return True def get_new_orders(self, updated_after: str) -> List[Dict[str, Any]]: """ Получить список новых заказов из Recommerce. Args: updated_after: Дата в формате 'Y-m-d-H-i-s' Returns: List[Dict]: Список DTO заказов (готовых для сохранения) """ raw_orders = self.client.get_orders(updated_after=updated_after) orders_dto = [] for raw_order in raw_orders: dto = from_api_order(raw_order) orders_dto.append(dto) return orders_dto def check_connection(self) -> bool: """Проверить соединение""" try: # Пробуем получить список заказов (легкий запрос) self.client.get_orders() return True except RecommerceError: return False