diff --git a/myproject/orders/models/delivery.py b/myproject/orders/models/delivery.py index a461c08..8aa0d55 100644 --- a/myproject/orders/models/delivery.py +++ b/myproject/orders/models/delivery.py @@ -168,7 +168,8 @@ class Delivery(models.Model): 'time_to': 'Время окончания доставки не может быть раньше времени начала' }) - def save(self, *args, **kwargs): + def save(self, *args, validate=True, **kwargs): """Переопределение save для вызова валидации""" - self.full_clean() + if validate: + self.full_clean() super().save(*args, **kwargs) diff --git a/myproject/orders/views.py b/myproject/orders/views.py index 36152f9..bfb67e6 100644 --- a/myproject/orders/views.py +++ b/myproject/orders/views.py @@ -68,26 +68,7 @@ def order_create(request): draft_items = [] if request.method == 'POST': - # Логирование POST-данных для отладки - print("\n=== POST DATA ===") - print(f"items-TOTAL_FORMS: {request.POST.get('items-TOTAL_FORMS')}") - print(f"items-INITIAL_FORMS: {request.POST.get('items-INITIAL_FORMS')}") - print(f"items-MIN_NUM_FORMS: {request.POST.get('items-MIN_NUM_FORMS')}") - print(f"items-MAX_NUM_FORMS: {request.POST.get('items-MAX_NUM_FORMS')}") - - # Показываем все формы товаров - total_forms = int(request.POST.get('items-TOTAL_FORMS', 0)) - for i in range(total_forms): - product = request.POST.get(f'items-{i}-product', '') - kit = request.POST.get(f'items-{i}-product_kit', '') - quantity = request.POST.get(f'items-{i}-quantity', '') - price = request.POST.get(f'items-{i}-price', '') - print(f"\nForm {i}:") - print(f" product: {product or '(пусто)'}") - print(f" kit: {kit or '(пусто)'}") - print(f" quantity: {quantity or '(пусто)'}") - print(f" price: {price or '(пусто)'}") - print("=== END POST DATA ===\n") + form = OrderForm(request.POST) formset = OrderItemFormSet(request.POST) @@ -175,13 +156,61 @@ def order_create(request): # Проверяем, является ли заказ черновиком is_draft = order.status and order.status.code == 'draft' - # Получаем данные из формы (уже провалидированы) - delivery_type = form.cleaned_data.get('delivery_type') - delivery_date = form.cleaned_data.get('delivery_date') - time_from = form.cleaned_data.get('time_from') - time_to = form.cleaned_data.get('time_to') - delivery_cost = form.cleaned_data.get('delivery_cost', Decimal('0')) - pickup_warehouse = form.cleaned_data.get('pickup_warehouse') + # ВАЖНО: Поля доставки НЕ включены в Meta.fields формы OrderForm, + # поэтому они не попадают в form.cleaned_data! + # Читаем их напрямую из request.POST и обрабатываем вручную + + # Получаем данные доставки из POST + delivery_type = request.POST.get('delivery_type', None) + + # Обрабатываем дату доставки + delivery_date_str = request.POST.get('delivery_date', None) + delivery_date = None + if delivery_date_str: + try: + from datetime import datetime + delivery_date = datetime.strptime(delivery_date_str, '%Y-%m-%d').date() + except (ValueError, TypeError): + pass + + # Обрабатываем время + time_from_str = request.POST.get('time_from', None) + time_from = None + if time_from_str: + try: + from datetime import datetime + time_from = datetime.strptime(time_from_str, '%H:%M').time() + except (ValueError, TypeError): + pass + + time_to_str = request.POST.get('time_to', None) + time_to = None + if time_to_str: + try: + from datetime import datetime + time_to = datetime.strptime(time_to_str, '%H:%M').time() + except (ValueError, TypeError): + pass + + # Обрабатываем стоимость доставки + delivery_cost_str = request.POST.get('delivery_cost', '0') + delivery_cost = Decimal('0') + if delivery_cost_str: + try: + delivery_cost = Decimal(delivery_cost_str.replace(',', '.')) + except (ValueError, TypeError): + pass + delivery_cost = Decimal('0') + + # Обрабатываем склад самовывоза + pickup_warehouse_id = request.POST.get('pickup_warehouse', None) + pickup_warehouse = None + if pickup_warehouse_id: + try: + from inventory.models import Warehouse + pickup_warehouse = Warehouse.objects.get(pk=pickup_warehouse_id) + except (Warehouse.DoesNotExist, ValueError): + pass # Обрабатываем адрес для курьерской доставки (даже для черновиков, если указан) address = None @@ -323,29 +352,9 @@ def order_update(request, order_number): form = OrderForm(request.POST, instance=order) formset = OrderItemFormSet(request.POST, instance=order) - # Логирование для отладки удаления позиций заказа - print("\n=== DEBUG ORDER UPDATE ===") - print(f"POST data keys: {list(request.POST.keys())}") - print(f"items-TOTAL_FORMS: {request.POST.get('items-TOTAL_FORMS')}") - print(f"items-INITIAL_FORMS: {request.POST.get('items-INITIAL_FORMS')}") - # Проверяем, какие формы были отмечены для удаления - total_forms = int(request.POST.get('items-TOTAL_FORMS', 0)) - for i in range(total_forms): - delete_field = request.POST.get(f'items-{i}-DELETE') - has_id = bool(request.POST.get(f'items-{i}-id')) - print(f"Form {i}: DELETE={delete_field}, has_id={has_id}") - print("=========================\n") - print(f"Form is valid: {form.is_valid()}") - print(f"Formset is valid: {formset.is_valid()}") - if not form.is_valid(): - print(f"Form errors: {form.errors}") - if not formset.is_valid(): - print(f"Formset errors: {formset.errors}") - for i, form_err in enumerate(formset.errors): - if form_err: - print(f"Form {i} errors: {form_err}") + if form.is_valid() and formset.is_valid(): try: @@ -364,38 +373,72 @@ def order_update(request, order_number): order.modified_by = request.user order.save() - print(f"Before formset.save(): Order has {order.items.count()} items") - # Логирование форм, отмеченных для удаления - print("Forms in formset:") - for i, form in enumerate(formset): - if hasattr(form, 'cleaned_data') and form.cleaned_data: - delete_flag = form.cleaned_data.get('DELETE', False) - form_id = form.cleaned_data.get('id') - print(f" Form {i}: id={form_id}, DELETE={delete_flag}, has_changed={form.has_changed()}") - print(f" Full cleaned_data: {form.cleaned_data}") - if delete_flag: - print(f" -> This form should be deleted") - else: - print(f" Form {i}: No cleaned_data or empty") + formset.save() - print(f"After formset.save(): Order has {order.items.count()} items") - print(f"Forms marked for deletion: {[form for form in formset if form.cleaned_data.get('DELETE')] if formset.can_delete else 'N/A'}") # Проверяем, является ли заказ черновиком is_draft = order.status and order.status.code == 'draft' - # Получаем данные из формы (уже провалидированы) - delivery_type = form.cleaned_data.get('delivery_type') - delivery_date = form.cleaned_data.get('delivery_date') - time_from = form.cleaned_data.get('time_from') - time_to = form.cleaned_data.get('time_to') - delivery_cost = form.cleaned_data.get('delivery_cost', Decimal('0')) - pickup_warehouse = form.cleaned_data.get('pickup_warehouse') + # ВАЖНО: Поля доставки НЕ включены в Meta.fields формы OrderForm, + # поэтому они не попадают в form.cleaned_data! + # Читаем их напрямую из request.POST и обрабатываем вручную + + # Получаем данные доставки из POST + delivery_type = request.POST.get('delivery_type', None) + + # Обрабатываем дату доставки + delivery_date_str = request.POST.get('delivery_date', None) + delivery_date = None + if delivery_date_str: + try: + from datetime import datetime + delivery_date = datetime.strptime(delivery_date_str, '%Y-%m-%d').date() + except (ValueError, TypeError): + pass + + # Обрабатываем время + time_from_str = request.POST.get('time_from', None) + time_from = None + if time_from_str: + try: + from datetime import datetime + time_from = datetime.strptime(time_from_str, '%H:%M').time() + except (ValueError, TypeError): + print(f"[DEBUG] Error parsing time_from: {time_from_str}") + + time_to_str = request.POST.get('time_to', None) + time_to = None + if time_to_str: + try: + from datetime import datetime + time_to = datetime.strptime(time_to_str, '%H:%M').time() + except (ValueError, TypeError): + pass + + # Обрабатываем стоимость доставки + delivery_cost_str = request.POST.get('delivery_cost', '0') + delivery_cost = Decimal('0') + if delivery_cost_str: + try: + delivery_cost = Decimal(delivery_cost_str.replace(',', '.')) + except (ValueError, TypeError): + pass + delivery_cost = Decimal('0') + + # Обрабатываем склад самовывоза + pickup_warehouse_id = request.POST.get('pickup_warehouse', None) + pickup_warehouse = None + if pickup_warehouse_id: + try: + from inventory.models import Warehouse + pickup_warehouse = Warehouse.objects.get(pk=pickup_warehouse_id) + except (Warehouse.DoesNotExist, ValueError): + pass + + - print(f"[DEBUG] Delivery data - type: {delivery_type}, date: {delivery_date}, time_from: {time_from}, time_to: {time_to}") - print(f"[DEBUG] Is draft: {is_draft}, address: {form.cleaned_data.get('address_street')}") # Обрабатываем адрес для курьерской доставки (даже для черновиков, если указан) address = None @@ -422,9 +465,9 @@ def order_update(request, order_number): 'cost': delivery_cost if delivery_cost else Decimal('0') } ) - print(f"[DEBUG] Created/Updated Delivery for draft: {delivery_obj.delivery_date}, created: {created}") + + elif hasattr(order, 'delivery'): - # Если заказ стал черновиком и нет данных доставки, удаляем Delivery order.delivery.delete() else: # Для не-черновиков проверяем обязательные поля @@ -453,7 +496,7 @@ def order_update(request, order_number): 'cost': delivery_cost if delivery_cost else Decimal('0') } ) - print(f"[DEBUG] Created/Updated Delivery for non-draft: {delivery.delivery_date}, created: {created}") + # Пересчитываем итоговую стоимость order.calculate_total() @@ -475,17 +518,7 @@ def order_update(request, order_number): # Транзакция откатилась, статус НЕ изменился messages.error(request, f'Ошибка при сохранении заказа: {e}') else: - # Логируем ошибки для отладки - print("\n=== ОШИБКИ ВАЛИДАЦИИ ФОРМЫ ===") - if not form.is_valid(): - print(f"OrderForm errors: {form.errors}") - if not formset.is_valid(): - print(f"OrderItemFormSet errors: {formset.errors}") - print(f"OrderItemFormSet non_form_errors: {formset.non_form_errors()}") - for i, item_form in enumerate(formset): - if item_form.errors: - print(f" Item form {i} errors: {item_form.errors}") - print("=== КОНЕЦ ОШИБОК ===\n") + messages.error(request, 'Пожалуйста, исправьте ошибки в форме.') else: form = OrderForm(instance=order)