feat: Улучшенная форма создания комплектов товаров

Реализованы следующие улучшения для формы создания/редактирования комплектов:

1. **Улучшенный API поиска товаров:**
   - Добавлен поиск по полю search_keywords для более точных результатов
   - Добавлены дополнительные поля: display_name, display_price

2. **Предпросмотр загружаемых фото:**
   - Миниатюры выбранных файлов перед загрузкой
   - Счетчик выбранных файлов
   - Возможность удаления отдельных фото до отправки формы

3. **Динамическое добавление товаров:**
   - Кнопка "Добавить товар в комплект" для создания новых строк
   - Автопоиск товаров при вводе текста (задержка 300мс)
   - Автоматическое добавление при клике на результат
   - Визуальные уведомления об успешном добавлении
   - Прокрутка к новой форме после добавления

4. **Валидация на дубликаты:**
   - Предупреждение при попытке добавить существующий товар
   - Подсветка дубликата на 2 секунды
   - Предложение изменить количество в существующей строке

5. **Автоматический расчет цены:**
   - Информационный блок с суммой товаров и их количеством
   - Пересчет при добавлении/удалении товаров
   - Пересчет при изменении количества
   - Асинхронная загрузка цен для существующих товаров

6. **Исправления:**
   - Снятие disabled с полей select перед отправкой формы
   - Правильное создание новых форм при добавлении товаров через поиск
   - Использование display_name для корректного отображения

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-23 15:52:29 +03:00
parent 9a232c6813
commit dd2b1f21f7
3 changed files with 545 additions and 71 deletions

View File

@@ -0,0 +1,133 @@
# Generated by Django 5.2.7 on 2025-10-23 12:13
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('products', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.AddField(
model_name='product',
name='deleted_at',
field=models.DateTimeField(blank=True, null=True, verbose_name='Время удаления'),
),
migrations.AddField(
model_name='product',
name='deleted_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='deleted_products', to=settings.AUTH_USER_MODEL, verbose_name='Удален пользователем'),
),
migrations.AddField(
model_name='product',
name='is_deleted',
field=models.BooleanField(db_index=True, default=False, verbose_name='Удален'),
),
migrations.AddField(
model_name='product',
name='slug',
field=models.SlugField(blank=True, max_length=200, unique=True, verbose_name='URL-идентификатор'),
),
migrations.AddField(
model_name='productcategory',
name='created_at',
field=models.DateTimeField(auto_now_add=True, null=True, verbose_name='Дата создания'),
),
migrations.AddField(
model_name='productcategory',
name='deleted_at',
field=models.DateTimeField(blank=True, null=True, verbose_name='Время удаления'),
),
migrations.AddField(
model_name='productcategory',
name='deleted_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='deleted_categories', to=settings.AUTH_USER_MODEL, verbose_name='Удалена пользователем'),
),
migrations.AddField(
model_name='productcategory',
name='is_deleted',
field=models.BooleanField(db_index=True, default=False, verbose_name='Удалена'),
),
migrations.AddField(
model_name='productcategory',
name='updated_at',
field=models.DateTimeField(auto_now=True, null=True, verbose_name='Дата обновления'),
),
migrations.AddField(
model_name='productkit',
name='deleted_at',
field=models.DateTimeField(blank=True, null=True, verbose_name='Время удаления'),
),
migrations.AddField(
model_name='productkit',
name='deleted_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='deleted_kits', to=settings.AUTH_USER_MODEL, verbose_name='Удален пользователем'),
),
migrations.AddField(
model_name='productkit',
name='is_deleted',
field=models.BooleanField(db_index=True, default=False, verbose_name='Удален'),
),
migrations.AddField(
model_name='producttag',
name='created_at',
field=models.DateTimeField(auto_now_add=True, null=True, verbose_name='Дата создания'),
),
migrations.AddField(
model_name='producttag',
name='deleted_at',
field=models.DateTimeField(blank=True, null=True, verbose_name='Время удаления'),
),
migrations.AddField(
model_name='producttag',
name='deleted_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='deleted_tags', to=settings.AUTH_USER_MODEL, verbose_name='Удален пользователем'),
),
migrations.AddField(
model_name='producttag',
name='is_deleted',
field=models.BooleanField(db_index=True, default=False, verbose_name='Удален'),
),
migrations.AddField(
model_name='producttag',
name='updated_at',
field=models.DateTimeField(auto_now=True, null=True, verbose_name='Дата обновления'),
),
migrations.AddIndex(
model_name='product',
index=models.Index(fields=['is_deleted'], name='products_pr_is_dele_3bba04_idx'),
),
migrations.AddIndex(
model_name='product',
index=models.Index(fields=['is_deleted', 'created_at'], name='products_pr_is_dele_f30efb_idx'),
),
migrations.AddIndex(
model_name='productcategory',
index=models.Index(fields=['is_deleted'], name='products_pr_is_dele_2a96d1_idx'),
),
migrations.AddIndex(
model_name='productcategory',
index=models.Index(fields=['is_deleted', 'created_at'], name='products_pr_is_dele_b8cdf3_idx'),
),
migrations.AddIndex(
model_name='productkit',
index=models.Index(fields=['is_deleted'], name='products_pr_is_dele_e83a83_idx'),
),
migrations.AddIndex(
model_name='productkit',
index=models.Index(fields=['is_deleted', 'created_at'], name='products_pr_is_dele_1e5bec_idx'),
),
migrations.AddIndex(
model_name='producttag',
index=models.Index(fields=['is_deleted'], name='products_pr_is_dele_ea9be0_idx'),
),
migrations.AddIndex(
model_name='producttag',
index=models.Index(fields=['is_deleted', 'created_at'], name='products_pr_is_dele_bc2d9c_idx'),
),
]