Упрощение генерации SKU: удалён автоматический суффикс варианта

Удалена функция parse_variant_suffix и логика автоматического добавления
суффикса варианта к артикулу товара. SKU теперь всегда имеет формат
PROD-XXXXXX без дополнительных суффиксов.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-02 23:50:26 +03:00
parent 973e20bf60
commit 7ccdbbdfb5
2 changed files with 17 additions and 89 deletions

View File

@@ -7,14 +7,13 @@
class ProductSaveService: class ProductSaveService:
""" """
Сервис для обработки сохранения Product. Сервис для обработки сохранения Product.
Извлекает variant_suffix, генерирует SKU и поисковые ключевые слова. Генерирует SKU и поисковые ключевые слова.
""" """
@staticmethod @staticmethod
def prepare_product_for_save(product): def prepare_product_for_save(product):
""" """
Подготавливает продукт к сохранению: Подготавливает продукт к сохранению:
- Извлекает variant_suffix из названия
- Генерирует SKU если не задан - Генерирует SKU если не задан
- Создает базовые поисковые ключевые слова - Создает базовые поисковые ключевые слова
@@ -24,13 +23,7 @@ class ProductSaveService:
Returns: Returns:
Product: Обновленный экземпляр продукта Product: Обновленный экземпляр продукта
""" """
from ..utils.sku_generator import parse_variant_suffix, generate_product_sku from ..utils.sku_generator import generate_product_sku
# Автоматическое извлечение variant_suffix из названия
if not product.variant_suffix and product.name:
parsed_suffix = parse_variant_suffix(product.name)
if parsed_suffix:
product.variant_suffix = parsed_suffix
# Генерация артикула для новых товаров # Генерация артикула для новых товаров
if not product.sku: if not product.sku:

View File

@@ -1,69 +1,21 @@
""" """
Utility functions for generating SKUs for products, kits, and categories. Утилиты для генерации артикулов (SKU) для товаров, комплектов и категорий.
New SKU format: Формат артикулов:
- Products: PROD-XXXXXX or PROD-XXXXXX-VARIANT - Товары: PROD-XXXXXX
- Kits: KIT-XXXXXX - Комплекты: KIT-XXXXXX
- Categories: CAT-XXXX - Категории: CAT-XXXX
- Configurable Products: VAR-XXXXXX - Вариативные товары: VAR-XXXXXX
Examples: Примеры:
- PROD-000001 - PROD-000001
- PROD-000002-50
- KIT-000001 - KIT-000001
- CAT-0001 - CAT-0001
- VAR-000001 - VAR-000001
""" """
import re
from string import ascii_uppercase from string import ascii_uppercase
def parse_variant_suffix(name):
"""
Извлекает суффикс варианта из названия товара.
Поддерживаемые форматы:
- "Роза Freedom 50см" -> "50"
- "Роза Freedom 60 см" -> "60"
- "Лента 2.5м" -> "25" (метры в дециметры)
- "Коробка S" -> "S"
- "Коробка размер M" -> "M"
Args:
name (str): Название товара
Returns:
str or None: Извлеченный суффикс или None
"""
if not name:
return None
# Паттерны для извлечения суффикса
patterns = [
# Размеры в см: "50см", "60 см"
(r'(\d+)\s*см', lambda m: m.group(1)),
# Размеры в метрах: "2.5м" -> "25" (конвертируем в дециметры)
(r'(\d+\.?\d*)\s*м(?:\s|$)', lambda m: str(int(float(m.group(1)) * 10))),
# Буквенные размеры в конце: "S", "M", "L", "XL"
(r'\b([XSML]{1,3})\s*$', lambda m: m.group(1)),
# "размер S", "размер M"
(r'размер\s+([XSML]{1,3})', lambda m: m.group(1)),
# Просто число в конце: "Товар 50"
(r'\s+(\d+)\s*$', lambda m: m.group(1)),
]
for pattern, extractor in patterns:
match = re.search(pattern, name, re.IGNORECASE)
if match:
return extractor(match)
return None
def ensure_sku_unique(base_sku, exclude_id=None, model_type=None): def ensure_sku_unique(base_sku, exclude_id=None, model_type=None):
""" """
Проверяет уникальность артикула и добавляет буквенный суффикс при конфликте. Проверяет уникальность артикула и добавляет буквенный суффикс при конфликте.
@@ -71,12 +23,12 @@ def ensure_sku_unique(base_sku, exclude_id=None, model_type=None):
Если артикул уже существует: Если артикул уже существует:
PROD-000001 -> PROD-000001A -> PROD-000001B -> ... -> PROD-000001Z PROD-000001 -> PROD-000001A -> PROD-000001B -> ... -> PROD-000001Z
Args: Аргументы:
base_sku (str): Базовый артикул для проверки base_sku (str): Базовый артикул для проверки
exclude_id (int): ID товара/комплекта/категории/вариативного товара, который нужно исключить из проверки exclude_id (int): ID товара/комплекта/категории/вариативного товара, который нужно исключить из проверки
model_type (str): Тип модели ('product', 'kit', 'category', 'configurable') для исключения из проверки model_type (str): Тип модели ('product', 'kit', 'category', 'configurable') для исключения из проверки
Returns: Возвращает:
str: Уникальный артикул str: Уникальный артикул
""" """
from products.models import Product, ProductKit, ProductCategory, ConfigurableProduct from products.models import Product, ProductKit, ProductCategory, ConfigurableProduct
@@ -134,12 +86,12 @@ def generate_product_sku(product):
""" """
Генерирует уникальный артикул для товара. Генерирует уникальный артикул для товара.
Формат: PROD-XXXXXX или PROD-XXXXXX-VARIANT Формат: PROD-XXXXXX
Args: Аргументы:
product: Экземпляр модели Product product: Экземпляр модели Product
Returns: Возвращает:
str: Сгенерированный артикул str: Сгенерированный артикул
""" """
from products.models import SKUCounter from products.models import SKUCounter
@@ -150,23 +102,6 @@ def generate_product_sku(product):
# Форматируем номер с ведущими нулями (6 цифр) # Форматируем номер с ведущими нулями (6 цифр)
base_sku = f"PROD-{next_number:06d}" base_sku = f"PROD-{next_number:06d}"
# Определяем суффикс варианта
variant_suffix = None
# 1. Если суффикс задан вручную в поле variant_suffix
if product.variant_suffix:
variant_suffix = product.variant_suffix.strip()
# 2. Если суффикс не задан, пытаемся извлечь из названия
# (это работает и для товаров в группах вариантов, и без них)
else:
parsed_suffix = parse_variant_suffix(product.name)
if parsed_suffix:
variant_suffix = parsed_suffix
# Добавляем суффикс, если он есть
if variant_suffix:
base_sku = f"{base_sku}-{variant_suffix}"
# Обеспечиваем уникальность # Обеспечиваем уникальность
unique_sku = ensure_sku_unique(base_sku, exclude_id=product.id if product.id else None, model_type='product') unique_sku = ensure_sku_unique(base_sku, exclude_id=product.id if product.id else None, model_type='product')
@@ -179,7 +114,7 @@ def generate_kit_sku():
Формат: KIT-XXXXXX Формат: KIT-XXXXXX
Returns: Возвращает:
str: Сгенерированный артикул str: Сгенерированный артикул
""" """
from products.models import SKUCounter from products.models import SKUCounter
@@ -202,7 +137,7 @@ def generate_category_sku():
Формат: CAT-XXXX (4 цифры) Формат: CAT-XXXX (4 цифры)
Returns: Возвращает:
str: Сгенерированный артикул str: Сгенерированный артикул
""" """
from products.models import SKUCounter from products.models import SKUCounter
@@ -225,7 +160,7 @@ def generate_configurable_sku():
Формат: VAR-XXXXXX Формат: VAR-XXXXXX
Returns: Возвращает:
str: Сгенерированный артикул str: Сгенерированный артикул
""" """
from products.models import SKUCounter from products.models import SKUCounter