From f6454c8ae58ad4a338ee32ebd90d5536a201e70c Mon Sep 17 00:00:00 2001 From: javad Date: Wed, 10 Jun 2026 21:59:26 +0330 Subject: [PATCH] view --- admin_panel/views.py | 62 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 14 deletions(-) diff --git a/admin_panel/views.py b/admin_panel/views.py index 221cece..2b3d3e2 100644 --- a/admin_panel/views.py +++ b/admin_panel/views.py @@ -9,13 +9,12 @@ from django.views.decorators.csrf import csrf_exempt from django.http import HttpResponse from django.urls import reverse from django.http import Http404, HttpResponseRedirect -from django.db.models import Count, Sum +from django.db.models import Count, Sum, Q, OuterRef, Subquery, Exists from django.contrib.auth.models import Permission, User from django.contrib.auth import authenticate, login, logout from django.contrib.auth.decorators import login_required, permission_required - +from django.db.models.functions import Coalesce from django.shortcuts import get_object_or_404 -from django.db.models import Q from .models import * @@ -573,25 +572,60 @@ def stores(request): data = {'all_store': all_store} return render(request, 'admin_panel/stores.html', data) + @login_required(login_url='/panel/p_login/') def store(request, s_id): productCategory = ProductCategory.objects.all() storeO = StoreRoom.objects.get(id=s_id) searchStatus = False - searchQS = request.POST.get('searchQS', '') + + # استفاده از .strip() برای پاک‌سازی فضاهای خالی احتمالی + searchQS = request.POST.get('searchQS', '').strip() mojodi = request.POST.get('mojodi', '') - #return HttpResponse(mojodi) - if searchQS !='': - productSum = Product.objects.filter(productinstore__StoreRoom=storeO ,productinstore__year=1400,product_name__contains=searchQS).annotate(mojodi=( Sum('productinstore__s_in') - Sum('productinstore__s_out') )) - if mojodi == "0": - productSum = productSum.filter(mojodi__lte=0) + + # ۱. ساب‌کوئری برای دریافت آخرین موجودی در لحظه تراکنش + # اضافه کردن '-id' به عنوان کلید دوم برای مواقعی که زمان‌ها دقیقاً برابرند + latest_stock_subquery = ProductInStore.objects.filter( + StoreRoom=storeO, + Product=OuterRef('pk'), + year=1400 + ).order_by('-createdDT', '-id').values('current_stock_at_time')[:1] + + # ۲. کوئری اصلی بهینه‌سازی شده با Exists (بدون JOIN سنگین و بدون نیاز به distinct) + products_qs = Product.objects.filter( + Exists( + ProductInStore.objects.filter( + StoreRoom=storeO, + Product=OuterRef('pk'), + year=1400 + ) + ) + ).annotate( + # اگر ساب‌کوئری NULL بود، به صورت پیش‌فرض مقدار 0 قرار داده می‌شود + mojodi=Coalesce(Subquery(latest_stock_subquery), 0) + ) + + # ۳. اعمال فیلتر جستجوی نام محصول + if searchQS != '': + productSum = products_qs.filter(product_name__contains=searchQS) searchStatus = True else: - productSum = Product.objects.filter(productinstore__StoreRoom=storeO ,productinstore__year=1400).annotate(mojodi=( Sum('productinstore__s_in') - Sum('productinstore__s_out') )) - if mojodi == "0": - searchStatus = True - productSum = productSum.filter(mojodi__lte=0) - data = {'storeO': storeO,'productSum': productSum, 's_id': s_id, 'searchStatus': searchStatus, "mojodi": mojodi, 'djsearchQS':searchQS, 'productCategory': productCategory} + productSum = products_qs + + # ۴. فیلتر وضعیت موجودی (حالا با خیال راحت روی عدد 0 فیلتر می‌شود) + if mojodi == "0": + productSum = productSum.filter(mojodi__lte=0) + searchStatus = True + + data = { + 'storeO': storeO, + 'productSum': productSum, + 's_id': s_id, + 'searchStatus': searchStatus, + "mojodi": mojodi, + 'djsearchQS': searchQS, + 'productCategory': productCategory + } return render(request, 'admin_panel/store.html', data) @login_required(login_url='/panel/p_login/')