diff --git a/myproject/products/templates/products/productkit_create.html b/myproject/products/templates/products/productkit_create.html index 893f274..c66c1ad 100644 --- a/myproject/products/templates/products/productkit_create.html +++ b/myproject/products/templates/products/productkit_create.html @@ -14,11 +14,11 @@ {% if form.non_field_errors or kititem_formset.non_form_errors %} - + {% endif %}
@@ -31,7 +31,7 @@
{{ form.name }} {% if form.name.errors %} -
{{ form.name.errors }}
+
{{ form.name.errors }}
{% endif %}
@@ -42,7 +42,7 @@ {{ form.description }} {% if form.description.errors %} -
{{ form.description.errors }}
+
{{ form.description.errors }}
{% endif %} @@ -54,7 +54,7 @@ {{ form.short_description }} Используется для карточек комплектов, превью и площадок {% if form.short_description.errors %} -
{{ form.short_description.errors }}
+
{{ form.short_description.errors }}
{% endif %} @@ -69,14 +69,15 @@
+ placeholder="Вставьте ссылку на изображение (https://...)">
- + @@ -88,17 +89,18 @@
- @@ -264,7 +284,7 @@ {{ form.tags }}
{% if form.tags.errors %} -
{{ form.tags.errors }}
+
{{ form.tags.errors }}
{% endif %}
@@ -279,7 +299,7 @@ {{ form.sku }} {% if form.sku.errors %} -
{{ form.sku.errors }}
+
{{ form.sku.errors }}
{% endif %} @@ -287,7 +307,7 @@ {{ form.status.label_tag }} {{ form.status }} {% if form.status.errors %} -
{{ form.status.errors }}
+
{{ form.status.errors }}
{% endif %} @@ -296,7 +316,8 @@ -
+
Отмена @@ -308,883 +329,920 @@
{% include 'products/includes/select2-product-init.html' %} +{{ selected_products|default:"{}"|json_script:"selected-products-data" }} +{{ selected_variants|default:"{}"|json_script:"selected-variants-data" }} +{{ selected_sales_units|default:"{}"|json_script:"selected-sales-units-data" }} + -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/myproject/products/templates/products/productkit_edit.html b/myproject/products/templates/products/productkit_edit.html index ca7a439..033e13c 100644 --- a/myproject/products/templates/products/productkit_edit.html +++ b/myproject/products/templates/products/productkit_edit.html @@ -506,6 +506,9 @@ Отмена + + Копировать комплект + diff --git a/myproject/products/views/productkit_views.py b/myproject/products/views/productkit_views.py index 9cd5553..4dfcbf6 100644 --- a/myproject/products/views/productkit_views.py +++ b/myproject/products/views/productkit_views.py @@ -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()