From 04ddc701a393d9633481430e4b39609c50bbcf3f Mon Sep 17 00:00:00 2001 From: javad Date: Fri, 31 Jul 2026 19:00:19 +0330 Subject: [PATCH] fix counter nazar, improve check, call button --- admin_panel/context_processor.py | 28 +- .../migrations/0056_auto_20260731_1824.py | 34 ++ admin_panel/models.py | 32 +- .../admin_panel/customerBaseNew.html | 38 +- .../admin_panel/customerSarresid.html | 562 ++++++++++++------ admin_panel/views.py | 107 +++- 6 files changed, 578 insertions(+), 223 deletions(-) create mode 100644 admin_panel/migrations/0056_auto_20260731_1824.py diff --git a/admin_panel/context_processor.py b/admin_panel/context_processor.py index 0ebd47c..39af797 100644 --- a/admin_panel/context_processor.py +++ b/admin_panel/context_processor.py @@ -1,24 +1,43 @@ -from django.db.models import Count, Sum -from django.db.models import Q +from django.db.models import Count, Sum, Q import os +import datetime from .models import * def dashBoxData(request): - bazdid = os.environ.get('bazdid', 9) debit = Article.objects.filter().aggregate(Sum('debit'))['debit__sum'] credit = Article.objects.filter().aggregate(Sum('credit'))['credit__sum'] + try: mandehesab = debit - credit except: mandehesab = 0 + countCustomers = Customer.objects.all().count() allUsers = User.objects.filter().exclude(username='admin').exclude(username='fesahat') ActionCount = Action.objects.filter(forUser=request.user.id, status='waite').count() - rezayatCount = Action.objects.exclude(actionType='vosol').filter(Q(nazar='') | Q(nazar=None) & Q(status='finish')).count() + + # --------------------------------------------------------- + # بخش اصلاح شده برای شمارش دقیق نظرسنجی‌های در انتظار + # --------------------------------------------------------- + now = datetime.datetime.now() + dt_30_days_ago = now - datetime.timedelta(days=30) + dt_60_days_ago = now - datetime.timedelta(days=60) + + rezayatCount = 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) # موعد پیگیری رسیده یا تعویقی نداشته باشد + ).count() + # --------------------------------------------------------- + try: entezarbazdid = CacheTable.objects.get(key='9mahbazdid').value except Exception as exp: @@ -33,4 +52,5 @@ def dashBoxData(request): 'entezarbazdid': entezarbazdid, 'bazdid': bazdid } + return data \ No newline at end of file diff --git a/admin_panel/migrations/0056_auto_20260731_1824.py b/admin_panel/migrations/0056_auto_20260731_1824.py new file mode 100644 index 0000000..f1022be --- /dev/null +++ b/admin_panel/migrations/0056_auto_20260731_1824.py @@ -0,0 +1,34 @@ +# Generated by Django 3.2.25 on 2026-07-31 14:54 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('admin_panel', '0055_action_nextnazardt'), + ] + + operations = [ + migrations.AddField( + model_name='sarresid', + name='check_owner_name', + field=models.CharField(blank=True, max_length=100, null=True, verbose_name='نام مالک چک'), + ), + migrations.AddField( + model_name='sarresid', + name='check_owner_phone', + field=models.CharField(blank=True, max_length=11, null=True, validators=[django.core.validators.RegexValidator(message='شماره تلفن باید ۱۱ رقم و فقط شامل اعداد باشد.', regex='^\\d{11}$')], verbose_name='تلفن مالک چک'), + ), + migrations.AddField( + model_name='sarresid', + name='check_row_number', + field=models.CharField(blank=True, max_length=50, null=True, verbose_name='شماره ردیف چک'), + ), + migrations.AddField( + model_name='sarresid', + name='check_sayyad_id', + field=models.CharField(blank=True, max_length=16, null=True, validators=[django.core.validators.RegexValidator(message='شناسه صیادی باید دقیقاً ۱۶ رقم عدد باشد.', regex='^\\d{16}$')], verbose_name='شناسه صیادی'), + ), + ] diff --git a/admin_panel/models.py b/admin_panel/models.py index b28861c..ea8b522 100644 --- a/admin_panel/models.py +++ b/admin_panel/models.py @@ -6,6 +6,7 @@ from django.dispatch import receiver from django.db import transaction, connection # اصلاح فیکس خطای تراکنش from django.contrib.auth.models import User from django.contrib.auth import get_user_model +from django.core.validators import RegexValidator userModel = get_user_model() @@ -467,17 +468,44 @@ class Action(models.Model): class Sarresid(models.Model): - customer = models.ForeignKey(Customer, on_delete=models.CASCADE, null=True, blank=True) + customer = models.ForeignKey('Customer', on_delete=models.CASCADE, null=True, blank=True) createdDT = models.DateTimeField(auto_now_add=True) changeDT = models.DateTimeField(auto_now=True) price = models.IntegerField(null=False, blank=False) payStatus = models.CharField(max_length=50, null=True, blank=True) type = models.CharField(max_length=50, null=True, blank=True) - factor = models.ForeignKey(Factor, on_delete=models.CASCADE, null=True, blank=True) + factor = models.ForeignKey('Factor', on_delete=models.CASCADE, null=True, blank=True) sarresidDT = models.DateTimeField(null=True, blank=True) user = models.ForeignKey(userModel, on_delete=models.SET_NULL, null=True, blank=True) desc = models.TextField(null=True, blank=True) + # ---------------- فیلدهای استاندارد و ایمن‌شده چک ---------------- + check_row_number = models.CharField( + max_length=50, + null=True, blank=True, + verbose_name="شماره ردیف چک" + ) + check_sayyad_id = models.CharField( + max_length=16, + validators=[ + RegexValidator(regex=r'^\d{16}$', message='شناسه صیادی باید دقیقاً ۱۶ رقم عدد باشد.') + ], + null=True, blank=True, + verbose_name="شناسه صیادی" + ) + check_owner_name = models.CharField( + max_length=100, + null=True, blank=True, + verbose_name="نام مالک چک" + ) + check_owner_phone = models.CharField( + max_length=11, + validators=[ + RegexValidator(regex=r'^\d{11}$', message='شماره تلفن باید ۱۱ رقم و فقط شامل اعداد باشد.') + ], + null=True, blank=True, + verbose_name="تلفن مالک چک" + ) class CacheTable(models.Model): key = models.CharField(max_length=50, unique=True) diff --git a/admin_panel/templates/admin_panel/customerBaseNew.html b/admin_panel/templates/admin_panel/customerBaseNew.html index d3999ac..18c3d29 100644 --- a/admin_panel/templates/admin_panel/customerBaseNew.html +++ b/admin_panel/templates/admin_panel/customerBaseNew.html @@ -45,38 +45,42 @@
- {% if customer.phones.all %} {% for phone_obj in customer.phones.all %}
-
+
+ {% if perms.admin_panel.ViewStore %}
{% endif %}
- {% if not perms.admin_panel.ViewStore %} -

- {{ phone_obj.title }}: {{ phone_obj.phone_number }} -

- {% endif %} {% endfor %} {% else %} {% if customer.phone1 %}
-
+
+ {% if perms.admin_panel.ViewStore %}
{% endif %} @@ -85,35 +89,43 @@ {% if customer.phone2 %}
-
+
+ {% if perms.admin_panel.ViewStore %}
{% endif %}
{% endif %} - + {% if customer.phone3 %}
-
+
+ {% if perms.admin_panel.ViewStore %}
{% endif %}
{% endif %} {% endif %} -
- {% if perms.admin_panel.ViewStore %} +
+
+ + {% if messages %} + {% for message in messages %} +
+ + {{ message }} +
+ {% endfor %} + {% endif %} {% if all_sarresid %} -
- +
+
- - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - + {% for sarresid in all_sarresid %} - + + + - - - - - - + + + + + + + + + + @@ -115,126 +210,159 @@
مبلغنوعسررسیدثبتتوضیحاتوضعیتوصول شد#مبلغ (تومان)نوعوضعیتعملیاتتاریخ سررسیدردیف چکشناسه صیادیصاحب حساب (تلفن)توضیحات / فاکتور
مبلغنوعسررسیدثبتتوضیحاتوضعیتوصول شد
{{ forloop.counter }} - {{ sarresid.price }} - + {{ sarresid.price }} - {% if sarresid.type == 'check' %}چک{% endif %} - {% if sarresid.type == 'nesiye' %}نسیه{% endif %} - - {{ sarresid.sarresidDT | toJalali }}{{ sarresid.createdDT | toJalali }} - {% if sarresid.desc %} - {{ sarresid.desc }} - {% endif %} - {% if sarresid.factor.id %} - فاکتور شماره {{ sarresid.factor.id }} + + + {% if sarresid.type == 'check' %} + چک + {% elif sarresid.type == 'nesiye' %} + نسیه {% endif %} - {% if sarresid.payStatus == "true" %}پرداخت شده{% endif %} - {% if sarresid.payStatus == "false" %}پرداخت نشده{% endif %} + + {% if sarresid.payStatus == "true" %} + + وصول شد + + {% else %} + + در انتظار + + {% endif %} - {% if sarresid.payStatus == "false" %} - وصول شد + + {% if sarresid.payStatus == "false" %} + {% else %} - بله + تسویه شده + {% endif %} + {{ sarresid.sarresidDT | toJalali }} + {{ sarresid.check_row_number|default:"-" }} + + {% if sarresid.check_sayyad_id %} + {{ sarresid.check_sayyad_id }} + {% else %} + - + {% endif %} + + {% if sarresid.check_owner_name %} +
{{ sarresid.check_owner_name }}
+ {% if sarresid.check_owner_phone %} +
{{ sarresid.check_owner_phone }}
+ {% endif %} + {% else %} + - + {% endif %} +
+ {% if sarresid.desc %} +

{{ sarresid.desc }}

+ {% endif %} + {% if sarresid.factor.id %} + فاکتور: {{ sarresid.factor.id }} {% endif %}
+ {% else %} +
+ هیچ سابقه چک یا نسیه‌ای برای این مشتری ثبت نشده است. +
{% endif %} -
- - -