From 825f2a59736ebbd893dadb5fc19803287cc541b0 Mon Sep 17 00:00:00 2001 From: javad Date: Wed, 21 Oct 2026 16:34:13 +0330 Subject: [PATCH] improve bazdid 4 --- .../management/commands/send_daily_report.py | 3 +- .../migrations/0080_action_soft_delete.py | 26 ++ admin_panel/models/actions.py | 19 ++ .../templates/admin_panel/customerAction.html | 2 +- .../admin_panel/customerActionInc.html | 77 +++++- admin_panel/urls.py | 1 + admin_panel/views/actions.py | 53 +++- admin_panel/views/finance.py | 11 +- admin_panel/views/sms.py | 4 +- admin_panel/visit_policy.py | 86 ++++++ docs/visit_hold_entezar.md | 56 ++++ tests/test_urls_contract.py | 2 + tests/test_visit_policy.py | 260 ++++++++++++++++++ 13 files changed, 585 insertions(+), 15 deletions(-) create mode 100644 admin_panel/migrations/0080_action_soft_delete.py diff --git a/admin_panel/management/commands/send_daily_report.py b/admin_panel/management/commands/send_daily_report.py index b399dd9..1621fd7 100644 --- a/admin_panel/management/commands/send_daily_report.py +++ b/admin_panel/management/commands/send_daily_report.py @@ -97,7 +97,8 @@ class Command(BaseCommand): # آمار نظرسنجی‌ها nazar_stats = Action.objects.filter( nazarDT__range=(today_start, today_end), - grade__gt=0 + grade__gt=0, + deleted_at__isnull=True, ).aggregate( avg_grade=Avg('grade'), total_count=Count('id') diff --git a/admin_panel/migrations/0080_action_soft_delete.py b/admin_panel/migrations/0080_action_soft_delete.py new file mode 100644 index 0000000..757c4fc --- /dev/null +++ b/admin_panel/migrations/0080_action_soft_delete.py @@ -0,0 +1,26 @@ +# Generated by Django 3.2.25 on 2026-10-21 12:31 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('admin_panel', '0079_customer_visit_hold'), + ] + + operations = [ + migrations.AddField( + model_name='action', + name='deleted_at', + field=models.DateTimeField(blank=True, default=None, help_text='اگر پر باشد، این اقدام توسط کاربر حذف شده است (status=cancell).', null=True, verbose_name='زمان حذف'), + ), + migrations.AddField( + model_name='action', + name='deleted_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='deleted_actions', to=settings.AUTH_USER_MODEL, verbose_name='حذف\u200cکننده'), + ), + ] diff --git a/admin_panel/models/actions.py b/admin_panel/models/actions.py index e85eeba..057aec6 100644 --- a/admin_panel/models/actions.py +++ b/admin_panel/models/actions.py @@ -67,6 +67,25 @@ class Action(models.Model): nazarDT = models.DateTimeField(null=True, blank=True, default=None) grade = models.IntegerField(null=True, blank=True, default=None) + # --- حسابرسی «حذف» (soft-delete از طریق status='cancell') --- + # چرا ستون جدا؟ چون ``cancell`` از قبل معنای «لغو برنامه» را دارد و در گزارش‌ها + # هم استفاده می‌شود. با این دو ستون می‌توانیم «حذف توسط کاربر» را از «لغو + # عادی» تفکیک کنیم، بدون آنکه منطق محاسبات (که فقط waite/finish را می‌بیند) + # دست بخورد. + deleted_at = models.DateTimeField( + null=True, blank=True, default=None, verbose_name="زمان حذف", + help_text="اگر پر باشد، این اقدام توسط کاربر حذف شده است (status=cancell).", + ) + deleted_by = models.ForeignKey( + User, on_delete=models.SET_NULL, null=True, blank=True, + related_name="deleted_actions", verbose_name="حذف‌کننده", + ) + + @property + def is_deleted(self): + """آیا این اقدام با «حذف» کنار گذاشته شده است؟ (نه لغو عادی)""" + return self.deleted_at is not None + class Meta: # ایندکس **پوشا (covering)** برای محاسبهٔ «آخرین بازدید»: هر سه ستونِ لازم # برای فیلتر و تجمیع داخل خودِ ایندکس است، پس دیتابیس به جدول اصلی مراجعه diff --git a/admin_panel/templates/admin_panel/customerAction.html b/admin_panel/templates/admin_panel/customerAction.html index 89ac942..74701db 100644 --- a/admin_panel/templates/admin_panel/customerAction.html +++ b/admin_panel/templates/admin_panel/customerAction.html @@ -4,7 +4,7 @@ {% block BodyCustomer1 %} -{% include 'admin_panel/customerActionInc.html' %} +{% include 'admin_panel/customerActionInc.html' with show_delete=True %}