Files
2026-10-21 10:50:42 +03:30

80 lines
5.0 KiB
Python

from django.db import models
class Customer(models.Model):
class Meta:
permissions = [
("AddCustomer", "AddCustomer"),
("DelCustomer", "DelCustomer"),
("EditCustomer", "EditCustomer"),
("ViewCustomer", "ViewCustomer")
]
name_family = models.CharField(max_length=200)
address = models.CharField(max_length=200)
# توضیحات آزاد مشتری؛ متن‌های غیرشماره‌ای که از فیلدهای تلفن پاک‌سازی می‌شوند
# اینجا نگه داشته می‌شوند تا هیچ داده‌ای از سیستم حذف نشود.
notes = models.TextField(
blank=True, default="", verbose_name="توضیحات",
help_text="یادداشت آزاد دربارهٔ مشتری؛ متن‌های حذف‌شدهٔ فیلدهای تلفن هم اینجا ثبت می‌شوند.",
)
phone1 = models.CharField(max_length=20, default='')
phone2 = models.CharField(max_length=20, default='', null=True, blank=True)
phone3 = models.CharField(max_length=20, default='', null=True, blank=True)
idCode = models.CharField(max_length=20, default='', null=True, blank=True)
installDate = models.DateField(auto_now_add=True)
create_date = models.DateTimeField(auto_now_add=True)
last_bazdid_dt = models.DateTimeField(null=True, blank=True)
laghv_bazdid = models.BooleanField(null=True, blank=True, default=False)
# فیلد جدید برای حذف نرم (بدون تداخل با داده‌های قبلی)
is_active = models.BooleanField(default=True, null=True, blank=True, help_text="وضعیت فعالیت مشتری")
# شماره‌های «اصلی» گیرندهٔ پیامک، به‌صورت مقدارِ خودِ شماره (نرمال‌شده، جدا با کاما).
# چرا مقدار و نه کلیدِ رکورد؟ چون دادهٔ مشتریان دائماً افزوده/ویرایش/حذف می‌شود و
# کلید رکورد در بازسازی‌ها از بین می‌رود؛ ولی شماره پایدار است. اگر شماره‌ای حذف یا
# ویرایش شود، این انتخاب خودبه‌خود بی‌اثر می‌شود و سیستم به شمارهٔ اول برمی‌گردد.
sms_primary_phones = models.CharField(
max_length=100, blank=True, default="",
verbose_name="شماره‌های اصلی پیامک",
help_text="شماره‌های نرمال‌شده (+98…) جدا‌شده با کاما؛ خالی = شمارهٔ اول مشتری.",
)
# ------------------------------------------------------------------
# «قرار بعدی» — تعویقِ دستیِ بازدید (تصمیم محصولی)
# ------------------------------------------------------------------
# این ستون **اعتبار مستقل ندارد**: فقط وقتی اثر دارد که یک اقدام «هماهنگی»
# فعال (``waite``/``finish``) با تاریخ آینده برای همان مشتری وجود داشته باشد.
# منبع حقیقت همچنان جدول ``Action`` است و این مقدار یک میان‌بر سریع برای
# نمایش/فیلتر است. اگر هماهنگی حذف/لغو شود، این مقدار خودبه‌خود بی‌اثر می‌شود
# (نگاه کنید به ``visit_policy.manual_holds_map``).
visit_hold_until = models.DateTimeField(
null=True, blank=True,
verbose_name="قرار بعدی (تعویق بازدید)",
help_text="تا پایان این روز پیگیری لازم نیست؛ از فرم «هماهنگی» تنظیم می‌شود.",
)
visit_hold_set_at = models.DateTimeField(
null=True, blank=True,
verbose_name="زمان ثبت قرار",
help_text="برای حسابرسی: آخرین باری که مقدار «قرار بعدی» نوشته شد.",
)
def __str__(self):
return self.name_family
# بازنویسی متد حذف: جلوگیری از فاجعه در دیتابیس
def delete(self, *args, **kwargs):
# به جای حذف فیزیکی که انبار و فاکتورها را نابود می‌کند، مشتری را غیرفعال می‌کنیم
self.is_active = False
self.save()
class PhoneNumber(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.CASCADE, related_name='phones')
title = models.CharField(max_length=50, default='تلفن', blank=True, null=True, help_text="عنوان شماره (مثل: موبایل پدر)")
phone_number = models.CharField(max_length=20)
# توجه: «شمارهٔ اصلی پیامک» روی خودِ Customer.sms_primary_phones نگه داشته می‌شود
# (کلیدش مقدار شماره است، نه رکورد) تا با افزودن/حذف/ویرایش مداوم مشتریان از بین نرود.
def __str__(self):
return f"{self.title}: {self.phone_number}"