fix nazar sanji and eghdamha

This commit is contained in:
javad committed 2026-07-24 22:11:52 +03:30
1 parent b86ccb373b
commit 6a6616f24a
8 files changed
+542 -91

No files matched your search

+139 -19
View File
@@ -13,7 +13,7 @@ from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseBadRequest # بخشBadRequest جدید
from django.db import transaction, connection
from django.db.models import Count, Sum, Q
from django.db.models import Count, Sum, Q, Avg
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
@@ -1930,11 +1930,39 @@ def customerHesabdariAdd(request ,c_id):
@login_required(login_url='/panel/p_login/')
def customerAction(request ,c_id):
customer = Customer.objects.get(id=c_id)
actions = Action.objects.filter(customer=customer).order_by("-createdDT")
def customerAction(request, c_id):
# استفاده از get_object_or_404 برای امنیت بیشتر
customer = get_object_or_404(Customer, id=c_id)
# دریافت پارامترهای فیلتر از URL (پیش‌فرض: all)
filter_type = request.GET.get('actionType', 'all')
filter_status = request.GET.get('status', 'all')
# کوئری پایه برای اقدامات این مشتری
actions = Action.objects.filter(customer=customer)
# اعمال فیلتر بر اساس نوع اقدام (بازدید، نصب و ...)
if filter_type != 'all':
actions = actions.filter(actionType=filter_type)
# اعمال فیلتر بر اساس وضعیت (انجام شده، در انتظار و ...)
if filter_status != 'all':
actions = actions.filter(status=filter_status)
# مرتب‌سازی نزولی بر اساس تاریخ ایجاد
actions = actions.order_by("-createdDT")
allUsers = User.objects.filter().exclude(username='admin').exclude(username='fesahat')
data = {'customer': customer, 'actions': actions, 'allUsers': allUsers}
data = {
'customer': customer,
'actions': actions,
'allUsers': allUsers,
# ارسال مقادیر فیلتر به قالب برای حفظ وضعیت انتخاب‌شده در دراپ‌داون‌ها
'filter_type': filter_type,
'filter_status': filter_status
}
return render(request, 'admin_panel/customerAction.html', data)
@login_required(login_url='/panel/p_login/')
@@ -2089,16 +2117,40 @@ def ActionListUserToday(request, u_id):
data = {'actions': actions, 'allUsers': allUsers, 'u_id': u_id, "unixADT": unixADT, "status": status, 'actionPr': actionPr}
return render(request, 'admin_panel/ActionList.html', data)
import datetime
from django.db.models import Q
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from .models import Action
@login_required(login_url='/panel/p_login/')
def rezayat(request):
dateTimeAction = request.GET.get('dateTime', None)
statusRezayat = request.GET.get('status', None)
status='finish'
if statusRezayat=='finish':
actions = Action.objects.exclude(actionType='vosol').exclude(Q(nazar='') | Q(nazar=None)).filter(status='finish').order_by("-id")[:50]
statusRezayat = request.GET.get('status', 'waite')
now = datetime.datetime.now()
# محاسبه بازه‌های زمانی ۳۰ روز و ۶۰ روز قبل
dt_30_days_ago = now - datetime.timedelta(days=30)
dt_60_days_ago = now - datetime.timedelta(days=60)
if statusRezayat == 'finish':
# نمایش نظرسنجی‌های تعیین‌تکلیف شده (ثبت شده یا کنسل شده)
actions = Action.objects.exclude(actionType='vosol').filter(
status='finish',
nazarDT__isnull=False
).order_by("-nazarDT")[:500]
else:
statusRezayat='waite'
actions = Action.objects.filter(Q(nazar='') | Q(nazar=None) & Q(status='finish')).exclude(actionType='vosol').order_by("id")[:50]
statusRezayat = 'waite'
# نمایش نظرسنجی‌های در انتظار با اعمال شرط عدم انقضای زمان
actions = Action.objects.exclude(actionType='vosol').filter(
status='finish',
nazarDT__isnull=True, # نظرسنجی هنوز نهایی نشده
createdDT__gte=dt_60_days_ago # حداکثر ۶۰ روز از ایجاد گذشته باشد
).filter(
Q(finishDateTime__isnull=True) | Q(finishDateTime__gte=dt_30_days_ago) # حداکثر ۳۰ روز از اتمام گذشته باشد
).filter(
Q(nextNazarDT__isnull=True) | Q(nextNazarDT__lte=now) # موعد پیگیری رسیده یا تعویقی نداشته باشد
).order_by("-id")[:500]
data = {'actions': actions, "status": statusRezayat}
return render(request, 'admin_panel/customerRezayat.html', data)
@@ -2107,19 +2159,87 @@ def rezayat(request):
def rezayatEdit(request, ac_id):
csGrade = request.POST.get('csGrade', None)
csDesc = request.POST.get('csDesc', None)
if csDesc and csGrade:
action = Action.objects.get(id=ac_id)
action.nazar = csDesc
action.grade = csGrade
action.nazarDT = datetime.datetime.now()
action = get_object_or_404(Action, id=ac_id)
if csGrade == '-1':
# عدم موفقیت: تنظیم nextNazarDT برای ۳ روز بعد (nazarDT پر نمی‌شود تا نهایی نشود)
action.nazar = csDesc
action.grade = int(csGrade)
action.nextNazarDT = datetime.datetime.now() + datetime.timedelta(days=3)
elif csGrade == '-2':
# کنسل کردن: پر کردن nazarDT برای خروج کامل از لیست کارهای در انتظار
action.nazar = csDesc
action.grade = int(csGrade)
action.nazarDT = datetime.datetime.now()
action.nextNazarDT = None
else:
# ثبت امتیاز عادی
action.nazar = csDesc
action.grade = int(csGrade)
action.nazarDT = datetime.datetime.now()
action.nextNazarDT = None
action.save()
return redirect('/panel/rezayat/')
else:
return HttpResponse('لطفا همه فیلد ها را پر کنید')
#data = {'actions': actions, "status": status}
#return render(request, 'admin_panel/customerRezayat.html', data)
return HttpResponse('لطفا همه فیلد ها را پر کنید')
@login_required(login_url='/panel/p_login/')
@permission_required('admin_panel.ViewReportMali', raise_exception=True)
def rezayat_dashboard(request):
# دریافت تمامی نظرسنجی‌های ثبت شده معتبر (که تاریخ نظرسنجی دارند)
valid_surveys = Action.objects.filter(
nazarDT__isnull=False,
grade__in=[5, 10, 15, 20]
)
# ۱. محاسبات شاخص‌های کلیدی (KPIs)
total_surveys = valid_surveys.count()
avg_grade = valid_surveys.aggregate(Avg('grade'))['grade__avg'] or 0
# ۲. استخراج داده‌ها برای نمودار توزیع رضایت
grade_distribution = valid_surveys.values('grade').annotate(count=Count('id'))
chart_dict = {20: 0, 15: 0, 10: 0, 5: 0}
for item in grade_distribution:
g = item['grade']
if g in chart_dict:
chart_dict[g] = item['count']
chart_labels = ['عالی (۲۰)', 'متوسط (۱۵)', 'ضعیف (۱۰)', 'بد (۵)']
chart_data_list = [chart_dict[20], chart_dict[15], chart_dict[10], chart_dict[5]]
# ۳. تبدیل امن آرایه‌ها به JSON برای Chart.js
chart_labels_json = json.dumps(chart_labels, ensure_ascii=False)
chart_data_json = json.dumps(chart_data_list)
has_chart_data = sum(chart_data_list) > 0
# ۴. واکشی لیست مشتریان نیازمند پیگیری (شامل متوسط ۱۵، ضعیف ۱۰ و بد ۵)
low_score_actions = Action.objects.filter(
nazarDT__isnull=False,
grade__in=[5, 10, 15] # <-- امتیاز ۱۵ (متوسط) نیز اضافه شد
).order_by('-nazarDT')
allUsers = User.objects.filter().exclude(username='admin').exclude(username='fesahat')
context = {
'total_surveys': total_surveys,
'avg_grade': round(avg_grade, 1),
'chart_labels_json': chart_labels_json,
'chart_data_json': chart_data_json,
'has_chart_data': has_chart_data,
'low_score_actions': low_score_actions,
# تعداد کل موارد نیازمند پیگیری (متوسط + ضعیف + بد)
'unhappy_count': chart_dict[15] + chart_dict[10] + chart_dict[5],
'allUsers': allUsers,
}
return render(request, 'admin_panel/report_rezayat.html', context)
@login_required(login_url='/panel/p_login/')
@permission_required('admin_panel.ViewStore', raise_exception=True)
def passCheck(request, articl_id):