Упрощение генерации 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:
@@ -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:
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user