feat: Add Product Kit creation and editing functionality with new views and templates.

This commit is contained in:
2026-01-25 00:09:45 +03:00
parent bf399996b8
commit 41e6c33683
3 changed files with 1393 additions and 1232 deletions

View File

@@ -9,7 +9,7 @@ from django.shortcuts import redirect
from django.db import transaction, IntegrityError
from user_roles.mixins import ManagerOwnerRequiredMixin
from ..models import ProductKit, ProductCategory, ProductTag, ProductKitPhoto, Product, ProductVariantGroup, BouquetName
from ..models import ProductKit, ProductCategory, ProductTag, ProductKitPhoto, Product, ProductVariantGroup, BouquetName, ProductSalesUnit
from ..forms import ProductKitForm, KitItemFormSetCreate, KitItemFormSetUpdate
from .utils import handle_photos
@@ -97,6 +97,28 @@ class ProductKitCreateView(LoginRequiredMixin, ManagerOwnerRequiredMixin, Create
form_class = ProductKitForm
template_name = 'products/productkit_create.html'
def get_initial(self):
initial = super().get_initial()
copy_id = self.request.GET.get('copy_from')
if copy_id:
try:
kit = ProductKit.objects.get(pk=copy_id)
initial.update({
'name': f"{kit.name} (Копия)",
'description': kit.description,
'short_description': kit.short_description,
'categories': list(kit.categories.values_list('pk', flat=True)),
'tags': list(kit.tags.values_list('pk', flat=True)),
'sale_price': kit.sale_price,
'price_adjustment_type': kit.price_adjustment_type,
'price_adjustment_value': kit.price_adjustment_value,
'external_category': kit.external_category,
'status': 'active', # Default to active for new kits
})
except ProductKit.DoesNotExist:
pass
return initial
def post(self, request, *args, **kwargs):
"""
Обрабатываем POST данные и очищаем ID товаров/комплектов от префиксов.
@@ -132,7 +154,6 @@ class ProductKitCreateView(LoginRequiredMixin, ManagerOwnerRequiredMixin, Create
context['kititem_formset'] = KitItemFormSetCreate(self.request.POST, prefix='kititem')
# При ошибке валидации: извлекаем выбранные товары для предзагрузки в Select2
from ..models import Product, ProductVariantGroup, ProductSalesUnit
selected_products = {}
selected_variants = {}
selected_sales_units = {}
@@ -195,7 +216,86 @@ class ProductKitCreateView(LoginRequiredMixin, ManagerOwnerRequiredMixin, Create
context['selected_variants'] = selected_variants
context['selected_sales_units'] = selected_sales_units
else:
context['kititem_formset'] = KitItemFormSetCreate(prefix='kititem')
# COPY KIT LOGIC
copy_id = self.request.GET.get('copy_from')
initial_items = []
selected_products = {}
selected_variants = {}
selected_sales_units = {}
if copy_id:
try:
source_kit = ProductKit.objects.get(pk=copy_id)
for item in source_kit.kit_items.all():
item_data = {
'quantity': item.quantity,
# Delete flag is false by default
}
form_prefix = f"kititem-{len(initial_items)}"
if item.product:
item_data['product'] = item.product
# Select2 prefill
product = item.product
text = product.name
if product.sku:
text += f" ({product.sku})"
actual_price = product.sale_price if product.sale_price else product.price
selected_products[f"{form_prefix}-product"] = {
'id': product.id,
'text': text,
'price': str(product.price) if product.price else None,
'actual_price': str(actual_price) if actual_price else '0'
}
if item.sales_unit:
item_data['sales_unit'] = item.sales_unit
# Select2 prefill
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:
item_data['variant_group'] = item.variant_group
# Select2 prefill
variant_group = ProductVariantGroup.objects.prefetch_related(
'items__product'
).get(id=item.variant_group.id)
variant_price = variant_group.price or 0
count = variant_group.items.count()
selected_variants[f"{form_prefix}-variant_group"] = {
'id': variant_group.id,
'text': f"{variant_group.name} ({count} вариантов)",
'price': str(variant_price),
'actual_price': str(variant_price),
'type': 'variant',
'count': count
}
initial_items.append(item_data)
except ProductKit.DoesNotExist:
pass
if initial_items:
context['kititem_formset'] = KitItemFormSetCreate(
prefix='kititem',
initial=initial_items
)
context['kititem_formset'].extra = len(initial_items)
else:
context['kititem_formset'] = KitItemFormSetCreate(prefix='kititem')
# Pass Select2 data to context
context['selected_products'] = selected_products
context['selected_variants'] = selected_variants
context['selected_sales_units'] = selected_sales_units
# Количество названий букетов в базе
context['bouquet_names_count'] = BouquetName.objects.count()