Исправлены 4 проблемы: 1. Расчёт цены первого товара - улучшена валидация в getProductPrice и calculateFinalPrice 2. Отображение actual_price в Select2 вместо обычной цены 3. Количество по умолчанию = 1 для новых форм компонентов 4. Auto-select текста при клике на поле количества для удобства редактирования Изменённые файлы: - products/forms.py: добавлен __init__ в KitItemForm для quantity.initial = 1 - products/templates/includes/select2-product-init.html: обновлена formatSelectResult - products/templates/productkit_create.html: добавлен focus handler для auto-select - products/templates/productkit_edit.html: добавлен focus handler для auto-select 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
117 lines
4.6 KiB
Python
117 lines
4.6 KiB
Python
# -*- coding: utf-8 -*-
|
||
from django.shortcuts import render, get_object_or_404
|
||
from django.views.generic import ListView, CreateView, UpdateView, DeleteView, View
|
||
from django.urls import reverse_lazy
|
||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||
from django.contrib import messages
|
||
from django.http import JsonResponse, HttpResponseRedirect
|
||
from django.views.decorators.http import require_http_methods
|
||
from django.utils.decorators import method_decorator
|
||
from ..models import Warehouse
|
||
from ..forms import WarehouseForm
|
||
|
||
|
||
class WarehouseListView(LoginRequiredMixin, ListView):
|
||
"""
|
||
Список всех складов тенанта
|
||
Сортирует по is_default (по умолчанию первым), потом по названию
|
||
"""
|
||
model = Warehouse
|
||
template_name = 'inventory/warehouse/warehouse_list.html'
|
||
context_object_name = 'warehouses'
|
||
paginate_by = 20
|
||
|
||
def get_queryset(self):
|
||
# Сортируем: сначала is_default DESC (по умолчанию первый), потом по названию
|
||
return Warehouse.objects.filter(is_active=True).order_by('-is_default', 'name')
|
||
|
||
|
||
class WarehouseCreateView(LoginRequiredMixin, CreateView):
|
||
"""
|
||
Создание нового склада
|
||
"""
|
||
model = Warehouse
|
||
form_class = WarehouseForm
|
||
template_name = 'inventory/warehouse/warehouse_form.html'
|
||
success_url = reverse_lazy('inventory:warehouse-list')
|
||
|
||
def form_valid(self, form):
|
||
messages.success(self.request, f'Склад "{form.instance.name}" успешно создан.')
|
||
return super().form_valid(form)
|
||
|
||
|
||
class WarehouseUpdateView(LoginRequiredMixin, UpdateView):
|
||
"""
|
||
Редактирование склада
|
||
"""
|
||
model = Warehouse
|
||
form_class = WarehouseForm
|
||
template_name = 'inventory/warehouse/warehouse_form.html'
|
||
success_url = reverse_lazy('inventory:warehouse-list')
|
||
|
||
def form_valid(self, form):
|
||
messages.success(self.request, f'Склад "{form.instance.name}" успешно обновлён.')
|
||
return super().form_valid(form)
|
||
|
||
|
||
class WarehouseDeleteView(LoginRequiredMixin, DeleteView):
|
||
"""
|
||
Удаление склада (мягкое удаление - деактивация).
|
||
Вместо физического удаления из БД, устанавливаем is_active=False
|
||
"""
|
||
model = Warehouse
|
||
template_name = 'inventory/warehouse/warehouse_confirm_delete.html'
|
||
success_url = reverse_lazy('inventory:warehouse-list')
|
||
|
||
def post(self, request, *args, **kwargs):
|
||
"""
|
||
Переопределяем POST метод чтобы использовать мягкое удаление
|
||
вместо стандартного физического удаления Django
|
||
"""
|
||
self.object = self.get_object()
|
||
warehouse_name = self.object.name
|
||
|
||
# Мягкое удаление - просто деактивируем склад
|
||
self.object.is_active = False
|
||
self.object.save()
|
||
|
||
messages.success(request, f'Склад "{warehouse_name}" архивирован и скрыт из списка.')
|
||
return HttpResponseRedirect(self.get_success_url())
|
||
|
||
|
||
@method_decorator(require_http_methods(["POST"]), name="dispatch")
|
||
class SetDefaultWarehouseView(LoginRequiredMixin, View):
|
||
"""
|
||
Установка склада по умолчанию
|
||
Обрабатывает POST запрос от AJAX и возвращает JSON ответ
|
||
"""
|
||
|
||
def post(self, request, pk):
|
||
"""
|
||
Установить склад с заданным pk как склад по умолчанию
|
||
"""
|
||
try:
|
||
warehouse = get_object_or_404(Warehouse, pk=pk, is_active=True)
|
||
|
||
# Установить этот склад как по умолчанию
|
||
# (метод save() в модели автоматически снимет флаг с других)
|
||
warehouse.is_default = True
|
||
warehouse.save()
|
||
|
||
return JsonResponse({
|
||
'status': 'success',
|
||
'message': f'Склад "{warehouse.name}" установлен по умолчанию',
|
||
'warehouse_id': warehouse.id,
|
||
'warehouse_name': warehouse.name
|
||
})
|
||
except Warehouse.DoesNotExist:
|
||
return JsonResponse({
|
||
'status': 'error',
|
||
'message': 'Склад не найден'
|
||
}, status=404)
|
||
except Exception as e:
|
||
return JsonResponse({
|
||
'status': 'error',
|
||
'message': str(e)
|
||
}, status=500)
|