add: akharin mojodi

This commit is contained in:
javad committed 2026-06-10 21:16:30 +03:30
1 parent 3b26ee3f93
commit 9eb1a9ef9b
2 files changed
+83 -56

No files matched your search

+38 -44
View File
@@ -4,6 +4,7 @@
{% block storeBody %} {% block storeBody %}
<p class="has-text-centered mt-2 mb-2 is-size-5">{{ storeO.store_name }}</p> <p class="has-text-centered mt-2 mb-2 is-size-5">{{ storeO.store_name }}</p>
<form class="columns m-0 is-multiline is-mobile" method="post"> <form class="columns m-0 is-multiline is-mobile" method="post">
{% csrf_token %} {% csrf_token %}
<div class="field column is-6-desktop is-6-mobile"> <div class="field column is-6-desktop is-6-mobile">
@@ -21,7 +22,6 @@
<option value="1">نقطه سفارش</option> <option value="1">نقطه سفارش</option>
</select> </select>
</div> </div>
</div> </div>
</div> </div>
@@ -30,10 +30,9 @@
<input type="submit" class="button is-link is-fullwidth" value="جستجو"/> <input type="submit" class="button is-link is-fullwidth" value="جستجو"/>
</div> </div>
</div> </div>
</form> </form>
<a class="button is-info mb-3 {% if searchStatus %} {% else %} is-hidden {% endif %}" href="{% url 'admin_panel:store' s_id %}">لغو جستجو و مشاهده همه</a> <a class="button is-info mb-3 {% if not searchStatus %}is-hidden{% endif %}" href="{% url 'admin_panel:store' s_id %}">لغو جستجو و مشاهده همه</a>
<div class="table-container"> <div class="table-container">
<table class="table m-auto has-text-centered table is-bordered is-striped is-narrow is-fullwidth mojodiTB"> <table class="table m-auto has-text-centered table is-bordered is-striped is-narrow is-fullwidth mojodiTB">
@@ -63,26 +62,21 @@
</td> </td>
<td class="product_price">{{ prd.product_price }}</td> <td class="product_price">{{ prd.product_price }}</td>
<td class="product_mojodi">{{ prd.mojodi }}</td> <td class="product_mojodi">{{ prd.mojodi }}</td>
<td> <td>
{% if perms.admin_panel.ViewStore %} {% if perms.admin_panel.ViewStore %}
<span class="Oedit_prd"><img style="width: 20px; height: 20px;" src="{% static 'admin_panel/icons/edit.png' %}"></span> <span class="Oedit_prd" style="cursor: pointer; margin-left: 5px;">
<img style="width: 20px; height: 20px;" src="{% static 'admin_panel/icons/edit.png' %}" alt="ویرایش">
</span>
<span class="delet_prd"><img style="width: 20px; height: 20px;" src="{% static 'admin_panel/icons/delet.png' %}"></span>
<span class="delet_prd" style="cursor: pointer; margin-left: 5px;">
<img style="width: 20px; height: 20px;" src="{% static 'admin_panel/icons/delet.png' %}" alt="حذف">
</span>
<a href="{% url 'admin_panel:newOperation' s_id prd.id %}"> <a href="{% url 'admin_panel:newOperation' s_id prd.id %}">
<span><img style="width: 20px; height: 20px;" src="{% static 'admin_panel/icons/add.png' %}"></span> <span><img style="width: 20px; height: 20px;" src="{% static 'admin_panel/icons/add.png' %}" alt="تراکنش جدید"></span>
</a> </a>
{% endif %} {% endif %}
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
@@ -97,25 +91,21 @@
<button class="delete close_edit" aria-label="close"></button> <button class="delete close_edit" aria-label="close"></button>
</header> </header>
<form action="{% url 'admin_panel:productEdit' %}" id="formcsEdit" class="has-background-white brad5" method="post"> <form action="{% url 'admin_panel:productEdit' %}" id="formcsEdit" class="has-background-white brad5" method="post">
<section class="modal-card-body">
{% csrf_token %} {% csrf_token %}
<section class="modal-card-body">
<input id="i_pcode" type="hidden" name="prd_code" value=""> <input id="i_pcode" type="hidden" name="prd_code" value="">
<div id="userDT" class="is-hidden-mobile"> <div id="userDT">
<div class="field column is-12-desktop is-12-mobile m-0"> <div class="field column is-12-desktop is-12-mobile m-0">
<label class="label">نام کالا</label> <label class="label">نام کالا</label>
<div class="control"> <div class="control">
<input id="EditnamePrd" required value="" name="namePrd" class="input an_name" type="text" placeholder="نام محصول"> <input id="EditnamePrd" required name="namePrd" class="input an_name" type="text" placeholder="نام محصول">
</div> </div>
</div> </div>
<div class="field column is-12-desktop is-12-mobile m-0"> <div class="field column is-12-desktop is-12-mobile m-0">
<label class="label">دسته کالا</label> <label class="label">دسته کالا</label>
<div class="control"> <div class="control">
<div class="select is-fullwidth"> <div class="select is-fullwidth">
<select id="Editcategory" name="category" required> <select id="Editcategory" name="category" required>
<option value=""></option> <option value=""></option>
@@ -124,60 +114,64 @@
{% endfor %} {% endfor %}
</select> </select>
</div> </div>
</div> </div>
</div> </div>
<div class="field column is-12-desktop is-12-mobile m-0"> <div class="field column is-12-desktop is-12-mobile m-0">
<label class="label">قیمت کالا</label> <label class="label">قیمت کالا</label>
<div class="control"> <div class="control">
<input id="Editproduct_price" required value="" name="price" class="input an_name" type="text" placeholder="قیمت"> <input id="Editproduct_price" required name="price" class="input an_name" type="text" placeholder="قیمت">
</div> </div>
</div> </div>
</div> </div>
</section> </section>
<footer class="modal-card-foot"> <footer class="modal-card-foot">
<input value="ذخیره" type="submit" class="button is-success"> <input value="ذخیره" type="submit" class="button is-success">
<button class="button close_edit">لغو</button> <button type="button" class="button close_edit">لغو</button>
</footer> </footer>
</form> </form>
</div> </div>
</div> </div>
<script> <script>
// مقداردهی اولیه به وضعیت فیلتر موجودی با امنیت بیشتر
var mojodiVar = "{{ mojodi }}";
if (mojodiVar !== '') {
$('#mojodi').val(mojodiVar);
}
{% if not mojodi %}
var mojodiVar = '';
{% else %}
var mojodiVar = {{ mojodi }};
{% endif %}
var objpname = null; var objpname = null;
$('#mojodi').val( mojodiVar ); // عملیات حذف کالا
$(".delet_prd").click(function(){ $(".delet_prd").click(function(){
var prd_id = $(this).parent().parent().attr('prd_id'); var prd_id = $(this).closest('tr').attr('prd_id');
if (confirm("از حذف مطمئن هستید؟")){ if (confirm("از حذف مطمئن هستید؟")){
window.location.href = '/panel/product/del/' + prd_id + "/" + "{{ s_id }}"; window.location.href = '/panel/product/del/' + prd_id + "/" + "{{ s_id }}";
} }
}); });
$(".close_edit").click(function(){
// بستن مودال ویرایش
$(".close_edit").click(function(e){
e.preventDefault();
$("#edit_prd").removeClass('is-active'); $("#edit_prd").removeClass('is-active');
}); });
// باز کردن مودال و مقداردهی فرم با داده‌های ردیف جاری
$(".Oedit_prd").click(function(){ $(".Oedit_prd").click(function(){
$("#edit_prd").addClass('is-active'); $("#edit_prd").addClass('is-active');
prd_id = $(this).parent().parent().attr("prd_id"); var tr = $(this).closest('tr');
p_cat = $(this).parent().parent().attr("p_cat");
objpname = $(this).parent().parent().find('.product_name') var prd_id = tr.attr("prd_id");
//alert($(this).parent().parent().find('.product_name')) var p_cat = tr.attr("p_cat");
objpname = tr.find('.product_name');
// استفاده از .text().trim() جهت حذف فضاهای خالی احتمالی ایجاد شده توسط تگ‌های قالب‌بندی
var currentName = tr.find('.product_name').text().trim();
var currentPrice = tr.find('.product_price').text().trim();
$("#i_pcode").val(prd_id); $("#i_pcode").val(prd_id);
$("#EditnamePrd").val( $(this).parent().parent().find('.product_name').html() ); $("#EditnamePrd").val(currentName);
$("#Editproduct_price").val( $(this).parent().parent().find('.product_price').html() ); $("#Editproduct_price").val(currentPrice);
$("#Editcategory").val(p_cat); $("#Editcategory").val(p_cat);
}); });
</script> </script>
+45 -12
View File
@@ -1,4 +1,4 @@
from django.shortcuts import redirect, render from django.shortcuts import redirect, render, get_object_or_404
from django.urls.base import reverse from django.urls.base import reverse
from persiantools.jdatetime import JalaliDate from persiantools.jdatetime import JalaliDate
from persiantools import characters, digits from persiantools import characters, digits
@@ -13,9 +13,8 @@ from django.db.models import Count, Sum
from django.contrib.auth.models import Permission, User from django.contrib.auth.models import Permission, User
from django.contrib.auth import authenticate, login, logout from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required, permission_required 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, OuterRef, Subquery, Exists
from django.db.models import Q
from .models import * from .models import *
@@ -578,20 +577,54 @@ def store(request, s_id):
productCategory = ProductCategory.objects.all() productCategory = ProductCategory.objects.all()
storeO = StoreRoom.objects.get(id=s_id) storeO = StoreRoom.objects.get(id=s_id)
searchStatus = False searchStatus = False
searchQS = request.POST.get('searchQS', '')
# استفاده از .strip() برای پاک‌سازی فضاهای خالی احتمالی
searchQS = request.POST.get('searchQS', '').strip()
mojodi = request.POST.get('mojodi', '') mojodi = request.POST.get('mojodi', '')
#return HttpResponse(mojodi)
# ۱. ساب‌کوئری برای دریافت آخرین موجودی در لحظه تراکنش
# اضافه کردن '-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 != '': 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') )) productSum = products_qs.filter(product_name__contains=searchQS)
if mojodi == "0":
productSum = productSum.filter(mojodi__lte=0)
searchStatus = True searchStatus = True
else: else:
productSum = Product.objects.filter(productinstore__StoreRoom=storeO ,productinstore__year=1400).annotate(mojodi=( Sum('productinstore__s_in') - Sum('productinstore__s_out') )) productSum = products_qs
# ۴. فیلتر وضعیت موجودی (حالا با خیال راحت روی عدد 0 فیلتر می‌شود)
if mojodi == "0": if mojodi == "0":
searchStatus = True
productSum = productSum.filter(mojodi__lte=0) productSum = productSum.filter(mojodi__lte=0)
data = {'storeO': storeO,'productSum': productSum, 's_id': s_id, 'searchStatus': searchStatus, "mojodi": mojodi, 'djsearchQS':searchQS, 'productCategory': productCategory} 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) return render(request, 'admin_panel/store.html', data)
@login_required(login_url='/panel/p_login/') @login_required(login_url='/panel/p_login/')