Исправлены 4 проблемы: 1. Расчёт цены первого товара - улучшена валидация в getProductPrice и calculateFinalPrice 2. Отображение actual_price в Select2 вместо обычной цены 3. Количество по умолчанию = 1 для новых форм компонентов 4. Auto-select текста при клике на поле количества для удобства редактирования Изменённые файлы: - products/forms.py: добавлен __init__ в KitItemForm для quantity.initial = 1 - products/templates/includes/select2-product-init.html: обновлена formatSelectResult - products/templates/productkit_create.html: добавлен focus handler для auto-select - products/templates/productkit_edit.html: добавлен focus handler для auto-select 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
69 lines
3.1 KiB
Python
69 lines
3.1 KiB
Python
"""
|
||
Сервисы для бизнес-логики Product модели.
|
||
Извлекает сложную логику из save() метода.
|
||
"""
|
||
|
||
|
||
class ProductSaveService:
|
||
"""
|
||
Сервис для обработки сохранения Product.
|
||
Извлекает variant_suffix, генерирует SKU и поисковые ключевые слова.
|
||
"""
|
||
|
||
@staticmethod
|
||
def prepare_product_for_save(product):
|
||
"""
|
||
Подготавливает продукт к сохранению:
|
||
- Извлекает variant_suffix из названия
|
||
- Генерирует SKU если не задан
|
||
- Создает базовые поисковые ключевые слова
|
||
|
||
Args:
|
||
product (Product): Экземпляр продукта
|
||
|
||
Returns:
|
||
Product: Обновленный экземпляр продукта
|
||
"""
|
||
from ..utils.sku_generator import parse_variant_suffix, 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:
|
||
product.sku = generate_product_sku(product)
|
||
|
||
# Автоматическая генерация ключевых слов для поиска
|
||
keywords_parts = [
|
||
product.name or '',
|
||
product.sku or '',
|
||
product.description or '',
|
||
]
|
||
|
||
if not product.search_keywords:
|
||
product.search_keywords = ' '.join(filter(None, keywords_parts))
|
||
|
||
return product
|
||
|
||
@staticmethod
|
||
def update_search_keywords_with_categories(product):
|
||
"""
|
||
Обновляет поисковые ключевые слова с названиями категорий.
|
||
Должен вызываться после сохранения, т.к. ManyToMany требует существующего объекта.
|
||
|
||
Args:
|
||
product (Product): Сохраненный экземпляр продукта
|
||
"""
|
||
# Добавляем названия категорий в search_keywords после сохранения
|
||
# (ManyToMany требует, чтобы объект уже существовал в БД)
|
||
if product.pk and product.categories.exists():
|
||
category_names = ' '.join([cat.name for cat in product.categories.all()])
|
||
if category_names and category_names not in product.search_keywords:
|
||
product.search_keywords = f"{product.search_keywords} {category_names}".strip()
|
||
# Используем update чтобы избежать рекурсии
|
||
from ..models.products import Product
|
||
Product.objects.filter(pk=product.pk).update(search_keywords=product.search_keywords)
|