feat(integrations): добавить поле primary_category и маппинг категорий для интеграций

Добавлена поддержка выбора основной категории (primary_category) для товаров и наборов, а также новая модель IntegrationCategoryMapping для связи категорий с внешними площадками. Теперь можно указать категорию товара, которая будет использоваться при экспорте на внешние площадки (Recommerce, WooCommerce и др.), с возможностью настройки маппинга категорий для каждого типа интеграции.
This commit is contained in:
2026-01-14 01:53:38 +03:00
parent 7fd361aaf8
commit 1fb280607a
14 changed files with 288 additions and 15 deletions

View File

@@ -207,6 +207,17 @@ class BaseProductEntity(models.Model):
verbose_name="Архивировано пользователем"
)
# Основная категория для интеграций
primary_category = models.ForeignKey(
'ProductCategory',
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='primary_%(class)ss',
verbose_name="Основная категория",
help_text="Используется для интеграций с внешними площадками"
)
# Manager
objects = models.Manager()
@@ -265,6 +276,43 @@ class BaseProductEntity(models.Model):
"""Возвращает True если товар активен"""
return self.status == 'active'
def get_category_for_integration(self, integration_type: str = 'recommerce'):
"""
Получить категорию товара для конкретной интеграции.
Приоритет:
1. primary_category (если указана и есть маппинг)
2. Первая категория из categories с существующим маппингом (если есть M2M)
Args:
integration_type: Тип интеграции ('recommerce', 'woocommerce')
Returns:
tuple: (ProductCategory, external_sku) или (None, None)
"""
from integrations.models import IntegrationCategoryMapping
# Приоритет 1: primary_category
if self.primary_category:
mapping = IntegrationCategoryMapping.objects.filter(
category=self.primary_category,
integration_type=integration_type
).first()
if mapping:
return self.primary_category, mapping.external_category_sku
# Приоритет 2: первая категория из M2M (если есть)
if hasattr(self, 'categories'):
for category in self.categories.all():
mapping = IntegrationCategoryMapping.objects.filter(
category=category,
integration_type=integration_type
).first()
if mapping:
return category, mapping.external_category_sku
return None, None
def save(self, *args, **kwargs):
"""
Автогенерация slug из name если не задан.