from typing import Any from django.shortcuts import render from django.views.generic import ListView, CreateView, UpdateView from django.urls import reverse_lazy from django.contrib.auth.views import LoginView from django.contrib import messages from django.db.models import Q from django.contrib.auth.mixins import UserPassesTestMixin from django.http import HttpResponseRedirect from extra_views import CreateWithInlinesView, UpdateWithInlinesView from django import forms from .models import Product, Supplier, Order, OrderItem from .forms import ProductForm, OrderForm, OrderItemFormSet class UserLoginView(LoginView): template_name = "core/login.html" class ProductListView(ListView): model = Product template_name = "core/product_list.html" context_object_name = "products" def get_queryset(self): queryset = Product.objects.all().select_related("supplier") search_query = self.request.GET.get("search", "") if search_query: queryset = queryset.filter( Q(name__icontains=search_query) | Q(description__icontains=search_query) | Q(manufacturer__icontains=search_query) | Q(category__icontains=search_query) ) supplier_id = self.request.GET.get("supplier", "") if supplier_id and supplier_id != 'all': queryset = queryset.filter(supplier_id=supplier_id) sort = self.request.GET.get("sort") if sort == "asc": queryset = queryset.order_by("quantity") if sort == "desc": queryset = queryset.order_by("-quantity") return queryset def get_context_data(self, **kwargs) -> dict[str, Any]: context = super().get_context_data(**kwargs) context["suppliers"] = Supplier.objects.all() context["current_supplier"] = self.request.GET.get("supplier", "") context["current_search"] = self.request.GET.get("search", "") context["current_sort"] = self.request.GET.get("sort", "") return context class AdminRequiredMixin(UserPassesTestMixin): def test_func(self): return ( self.request.user.is_authenticated and self.request.user.role and self.request.user.role.name == "Администратор" ) class ProductCreateUpdateMixin: def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["all_suppliers"] = Supplier.objects.all() return context class ProductCreateView(AdminRequiredMixin, ProductCreateUpdateMixin, CreateView): model = Product form_class = ProductForm template_name = "core/product_form.html" success_url = reverse_lazy("product_list") def form_valid(self, form): messages.success(self.request, "Товар успешно добавлен") return super().form_valid(form) class ProductUpdateView(AdminRequiredMixin, ProductCreateUpdateMixin, UpdateView): model = Product form_class = ProductForm template_name = "core/product_form.html" success_url = reverse_lazy("product_list") def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["is_edit"] = True return context class AdminManagerRequiredMixin(UserPassesTestMixin): def test_func(self): return ( self.request.user.is_authenticated and self.request.user.role and (self.request.user.role.name == "Администратор" or self.request.user.role.name == "Менеджер") ) class OrderListView(AdminManagerRequiredMixin, ListView): model = Order template_name = "core/order_list.html" context_object_name = "orders" class OrderCreateView(CreateWithInlinesView): model = Order form_class = OrderForm inlines = [OrderItemFormSet] success_url = reverse_lazy("order_list") class OrderUpdateView(UpdateWithInlinesView): model = Order form_class = OrderForm inlines = [OrderItemFormSet] success_url = reverse_lazy("order_list") # formset variant # class OrderCreateView(CreateView): # model = Order # form_class = OrderForm # template_name = "core/order_form.html" # success_url = reverse_lazy("order_list") # def get_context_data(self, **kwargs): # context = super().get_context_data(**kwargs) # if self.request.POST: # # re-use the bound formset if post() already stashed an invalid one # context["formset"] = getattr(self, "formset", OrderItemFormSet(self.request.POST)) # else: # context["formset"] = OrderItemFormSet() # return context # def post(self, request, *args, **kwargs): # self.object = None # form = self.get_form() # formset = OrderItemFormSet(request.POST) # if form.is_valid() and formset.is_valid(): # self.object = form.save() # formset.instance = self.object # formset.save() # return HttpResponseRedirect(self.get_success_url()) # # stash the invalid formset so get_context_data renders it with errors # self.formset = formset # return self.form_invalid(form) # class OrderUpdateView(UpdateView): # model = Order # form_class = OrderForm # template_name = "core/order_form.html" # success_url = reverse_lazy("order_list") # def get_context_data(self, **kwargs): # context = super().get_context_data(**kwargs) # if self.request.POST: # context["formset"] = getattr( # self, "formset", OrderItemFormSet(self.request.POST, instance=self.object) # ) # else: # context["formset"] = OrderItemFormSet(instance=self.object) # return context # def post(self, request, *args, **kwargs): # self.object = self.get_object() # form = self.get_form() # formset = OrderItemFormSet(request.POST, instance=self.object) # if form.is_valid() and formset.is_valid(): # form.save() # formset.save() # return HttpResponseRedirect(self.get_success_url()) # self.formset = formset # return self.form_invalid(form)