Fix: Implement proper deletion of order items with confirmation dialog
Fixes deletion functionality for order items across frontend and backend: - Remove restriction preventing deletion of last item - Add confirmation dialog before deletion - Properly track and send deleted item IDs to backend via autosave - Update backend to handle item deletion by ID instead of index - Fix visual feedback: deleted items are hidden immediately - Auto-recalculate total sum after deletion Technical changes: - order_form.html: Add confirmation dialog, trigger autosave on delete - autosave.js: Collect deleted item IDs, send to backend - draft_service.py: Process deleted_item_ids, update items by ID 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -73,7 +73,7 @@ def search_products_and_variants(request):
|
||||
numeric_id = int(item_id)
|
||||
|
||||
if item_type == 'product':
|
||||
product = Product.objects.get(id=numeric_id, is_active=True)
|
||||
product = Product.objects.get(id=numeric_id, status='active')
|
||||
return JsonResponse({
|
||||
'results': [{
|
||||
'id': f'product_{product.id}',
|
||||
@@ -89,7 +89,7 @@ def search_products_and_variants(request):
|
||||
elif item_type == 'kit':
|
||||
# Для комплектов: временные комплекты можно получать по ID (для заказов)
|
||||
# но не показываем их в общем поиске
|
||||
kit = ProductKit.objects.get(id=numeric_id, is_active=True)
|
||||
kit = ProductKit.objects.get(id=numeric_id, status='active')
|
||||
return JsonResponse({
|
||||
'results': [{
|
||||
'id': f'kit_{kit.id}',
|
||||
@@ -170,7 +170,7 @@ def search_products_and_variants(request):
|
||||
|
||||
if search_type in ['all', 'kit']:
|
||||
# Показываем последние добавленные активные комплекты (только постоянные)
|
||||
kits = ProductKit.objects.filter(is_active=True, is_temporary=False)\
|
||||
kits = ProductKit.objects.filter(status='active', is_temporary=False)\
|
||||
.order_by('-created_at')[:page_size]\
|
||||
.values('id', 'name', 'sku', 'price', 'sale_price')
|
||||
|
||||
@@ -244,7 +244,7 @@ def search_products_and_variants(request):
|
||||
models.Q(name_lower__contains=query_lower) |
|
||||
models.Q(sku_lower__contains=query_lower) |
|
||||
models.Q(description_lower__contains=query_lower),
|
||||
is_active=True
|
||||
status='active'
|
||||
).annotate(
|
||||
relevance=Case(
|
||||
When(name_lower=query_lower, then=3),
|
||||
@@ -259,7 +259,7 @@ def search_products_and_variants(request):
|
||||
models.Q(name__icontains=query_normalized) |
|
||||
models.Q(sku__icontains=query_normalized) |
|
||||
models.Q(description__icontains=query_normalized),
|
||||
is_active=True
|
||||
status='active'
|
||||
).annotate(
|
||||
relevance=Case(
|
||||
When(name__iexact=query_normalized, then=3),
|
||||
@@ -310,7 +310,7 @@ def search_products_and_variants(request):
|
||||
models.Q(name_lower__contains=query_lower) |
|
||||
models.Q(sku_lower__contains=query_lower) |
|
||||
models.Q(description_lower__contains=query_lower),
|
||||
is_active=True,
|
||||
status='active',
|
||||
is_temporary=False
|
||||
).annotate(
|
||||
relevance=Case(
|
||||
@@ -325,7 +325,7 @@ def search_products_and_variants(request):
|
||||
models.Q(name__icontains=query_normalized) |
|
||||
models.Q(sku__icontains=query_normalized) |
|
||||
models.Q(description__icontains=query_normalized),
|
||||
is_active=True,
|
||||
status='active',
|
||||
is_temporary=False
|
||||
).annotate(
|
||||
relevance=Case(
|
||||
@@ -498,7 +498,7 @@ def validate_kit_cost(request):
|
||||
elif variant_group_id:
|
||||
try:
|
||||
variant_group = ProductVariantGroup.objects.get(id=variant_group_id)
|
||||
product = variant_group.products.filter(is_active=True).first()
|
||||
product = variant_group.products.filter(status='active').first()
|
||||
if variant_group:
|
||||
product_name = f"[Варианты] {variant_group.name}"
|
||||
except ProductVariantGroup.DoesNotExist:
|
||||
|
||||
Reference in New Issue
Block a user