80 lines
5.0 KiB
Python
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}"
|