Исправление ошибок в редактировании комплектов: валидация, верстка, расчет цены

This commit is contained in:
2026-01-21 10:16:37 +03:00
parent 2dc36b3d01
commit e138a28475
12 changed files with 1447 additions and 658 deletions

View File

@@ -208,6 +208,15 @@ class ProductDetailView(LoginRequiredMixin, ManagerOwnerRequiredMixin, DetailVie
# Единицы продажи (активные, отсортированные)
context['sales_units'] = self.object.sales_units.filter(is_active=True).order_by('position', 'name')
# Комплекты, в которых этот товар используется как единица продажи
context['kit_items_using_sales_units'] = self.object.kit_items_using_as_sales_unit.select_related('kit', 'sales_unit').prefetch_related('kit__photos')
# Комплекты, в которых этот товар используется напрямую
context['kit_items_using_products'] = self.object.kit_items_direct.select_related('kit').prefetch_related('kit__photos')
# Комплекты, в которых этот товар используется как часть группы вариантов
context['variant_group_kit_items'] = self.object.variant_group_items.select_related('variant_group').prefetch_related('variant_group__kit_items__kit__photos')
return context

View File

@@ -113,6 +113,12 @@ class ProductKitCreateView(LoginRequiredMixin, ManagerOwnerRequiredMixin, Create
# Извлекаем числовой ID из "product_123"
numeric_id = value.split('_')[1]
post_data[key] = numeric_id
elif key.endswith('-sales_unit') and post_data[key]:
value = post_data[key]
if '_' in value:
# Извлекаем числовой ID из "sales_unit_123"
numeric_id = value.split('_')[1]
post_data[key] = numeric_id
# Заменяем request.POST на очищенные данные
request.POST = post_data
@@ -126,9 +132,10 @@ class ProductKitCreateView(LoginRequiredMixin, ManagerOwnerRequiredMixin, Create
context['kititem_formset'] = KitItemFormSetCreate(self.request.POST, prefix='kititem')
# При ошибке валидации: извлекаем выбранные товары для предзагрузки в Select2
from ..models import Product, ProductVariantGroup
from ..models import Product, ProductVariantGroup, ProductSalesUnit
selected_products = {}
selected_variants = {}
selected_sales_units = {}
for key, value in self.request.POST.items():
if '-product' in key and value:
@@ -168,8 +175,25 @@ class ProductKitCreateView(LoginRequiredMixin, ManagerOwnerRequiredMixin, Create
except ProductVariantGroup.DoesNotExist:
pass
if '-sales_unit' in key and value:
try:
sales_unit = ProductSalesUnit.objects.select_related('product').get(id=value)
text = f"{sales_unit.name} ({sales_unit.product.name})"
# Получаем actual_price: приоритет sale_price > price
actual_price = sales_unit.sale_price if sales_unit.sale_price else sales_unit.price
selected_sales_units[key] = {
'id': sales_unit.id,
'text': text,
'price': str(sales_unit.price) if sales_unit.price else None,
'actual_price': str(actual_price) if actual_price else '0'
}
except ProductSalesUnit.DoesNotExist:
pass
context['selected_products'] = selected_products
context['selected_variants'] = selected_variants
context['selected_sales_units'] = selected_sales_units
else:
context['kititem_formset'] = KitItemFormSetCreate(prefix='kititem')
@@ -271,6 +295,12 @@ class ProductKitUpdateView(LoginRequiredMixin, ManagerOwnerRequiredMixin, Update
# Извлекаем числовой ID из "product_123"
numeric_id = value.split('_')[1]
post_data[key] = numeric_id
elif key.endswith('-sales_unit') and post_data[key]:
value = post_data[key]
if '_' in value:
# Извлекаем числовой ID из "sales_unit_123"
numeric_id = value.split('_')[1]
post_data[key] = numeric_id
# Заменяем request.POST на очищенные данные
request.POST = post_data
@@ -284,8 +314,10 @@ class ProductKitUpdateView(LoginRequiredMixin, ManagerOwnerRequiredMixin, Update
context['kititem_formset'] = KitItemFormSetUpdate(self.request.POST, instance=self.object, prefix='kititem')
# При ошибке валидации - подготавливаем данные для Select2
from ..models import Product, ProductVariantGroup, ProductSalesUnit
selected_products = {}
selected_variants = {}
selected_sales_units = {}
for key, value in self.request.POST.items():
if '-product' in key and value:
@@ -328,14 +360,35 @@ class ProductKitUpdateView(LoginRequiredMixin, ManagerOwnerRequiredMixin, Update
except ProductVariantGroup.DoesNotExist:
pass
if '-sales_unit' in key and value:
try:
# Очищаем ID от префикса если есть
numeric_value = value.split('_')[1] if '_' in value else value
sales_unit = ProductSalesUnit.objects.select_related('product').get(id=numeric_value)
text = f"{sales_unit.name} ({sales_unit.product.name})"
# Получаем actual_price: приоритет sale_price > price
actual_price = sales_unit.sale_price if sales_unit.sale_price else sales_unit.price
selected_sales_units[key] = {
'id': sales_unit.id,
'text': text,
'price': str(sales_unit.price) if sales_unit.price else None,
'actual_price': str(actual_price) if actual_price else '0'
}
except ProductSalesUnit.DoesNotExist:
pass
context['selected_products'] = selected_products
context['selected_variants'] = selected_variants
context['selected_sales_units'] = selected_sales_units
else:
context['kititem_formset'] = KitItemFormSetUpdate(instance=self.object, prefix='kititem')
# Подготавливаем данные для предзагрузки в Select2
from ..models import Product, ProductVariantGroup, ProductSalesUnit
selected_products = {}
selected_variants = {}
selected_sales_units = {}
for item in self.object.kit_items.all():
form_prefix = f"kititem-{item.id}"
@@ -354,6 +407,17 @@ class ProductKitUpdateView(LoginRequiredMixin, ManagerOwnerRequiredMixin, Update
'actual_price': str(actual_price) if actual_price else '0'
}
if item.sales_unit:
sales_unit = item.sales_unit
text = f"{sales_unit.name} ({sales_unit.product.name})"
actual_price = sales_unit.sale_price if sales_unit.sale_price else sales_unit.price
selected_sales_units[f"{form_prefix}-sales_unit"] = {
'id': sales_unit.id,
'text': text,
'price': str(sales_unit.price) if sales_unit.price else None,
'actual_price': str(actual_price) if actual_price else '0'
}
if item.variant_group:
variant_group = ProductVariantGroup.objects.prefetch_related(
'items__product'
@@ -373,6 +437,7 @@ class ProductKitUpdateView(LoginRequiredMixin, ManagerOwnerRequiredMixin, Update
context['selected_products'] = selected_products
context['selected_variants'] = selected_variants
context['selected_sales_units'] = selected_sales_units
context['productkit_photos'] = self.object.photos.all().order_by('order', 'created_at')
context['photos_count'] = self.object.photos.count()