sms
This commit is contained in:
1 parent
250cdbab7f
commit
5c6069c3ef
87 files changed
+29209
-3697
No files matched your search
@@ -0,0 +1,119 @@
|
||||
"""یکسانسازی شمارههای اصلی + زمانبندی اختصاصی هر نوع پیامک.
|
||||
|
||||
* «شمارهٔ اصلی» از رکورد ``PhoneNumber`` به خودِ ``Customer`` منتقل میشود و با مقدارِ
|
||||
نرمالشدهٔ شماره ذخیره میگردد تا با افزودن/حذف/ویرایش مداوم مشتریان پایدار بماند.
|
||||
* فیلد زمانی هر قالب با معنای واقعی همان نوع همراستا میشود (مثلاً نظرسنجی = ۳ روز بعد
|
||||
از صدور فاکتور، و یادآوری ثبت چک = هر ۳ روز تا ثبت اطلاعات چک).
|
||||
"""
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
def _normalize(raw):
|
||||
"""نرمالسازی شماره (بدون وابستگی به کد اپ، برای اجرای امن روی دادهٔ قدیمی)."""
|
||||
from integrations.sms.normalize import normalize_mobile
|
||||
|
||||
return normalize_mobile(raw)
|
||||
|
||||
|
||||
def backfill_primary_phones(apps, schema_editor):
|
||||
"""پرچمهای ``is_primary`` موجود را به مقدار نرمالشده روی مشتری منتقل میکند."""
|
||||
PhoneNumber = apps.get_model("admin_panel", "PhoneNumber")
|
||||
for customer_id, phone_number in (
|
||||
PhoneNumber.objects.filter(is_primary=True)
|
||||
.values_list("customer_id", "phone_number")
|
||||
):
|
||||
normalized = _normalize((phone_number or "").strip())
|
||||
if not normalized:
|
||||
continue
|
||||
customer = apps.get_model("admin_panel", "Customer").objects.filter(pk=customer_id).first()
|
||||
if customer is None:
|
||||
continue
|
||||
current = [p for p in (customer.sms_primary_phones or "").split(",") if p]
|
||||
if normalized in current:
|
||||
continue
|
||||
current.append(normalized)
|
||||
customer.sms_primary_phones = ",".join(current)
|
||||
customer.save(update_fields=["sms_primary_phones"])
|
||||
|
||||
|
||||
def normalize_template_timing(apps, schema_editor):
|
||||
"""مقادیر زمانیِ بیمعنی را با معنای درست هر نوع پیامک همراستا میکند.
|
||||
|
||||
فقط مقادیری که برای آن نوع معنا ندارند اصلاح میشوند؛ تنظیمات معنادارِ مدیر دستنخورده
|
||||
میماند.
|
||||
"""
|
||||
SMSTemplate = apps.get_model("admin_panel", "SMSTemplate")
|
||||
|
||||
# نظرسنجی: «۳ روز بعد از صدور فاکتور» (مقدار پیشین ۲ بود).
|
||||
SMSTemplate.objects.filter(sms_type="survey", offset_days=2).update(offset_days=3)
|
||||
|
||||
# یادآوری ثبت چک: فاصله تکرار ۳ روز و بدون offset سررسید.
|
||||
for template in SMSTemplate.objects.filter(sms_type="cheque_registration"):
|
||||
template.offset_days = 0
|
||||
if not template.repeat_interval_days:
|
||||
template.repeat_interval_days = 3
|
||||
template.save(update_fields=["offset_days", "repeat_interval_days"])
|
||||
|
||||
# یادآوری بازدید: دورهٔ پیشفرض ۹ ماه (قابل تغییر از پنل).
|
||||
SMSTemplate.objects.filter(
|
||||
sms_type="visit", repeat_interval_months__isnull=True,
|
||||
).update(repeat_interval_months=9)
|
||||
|
||||
# متن «یادآوری ثبت چک» به معنای جدید (ثبت اطلاعات چک) همراستا میشود.
|
||||
SMSTemplate.objects.filter(sms_type="cheque_registration").update(
|
||||
title="یادآوری ثبت اطلاعات چک",
|
||||
text="{name} عزیز، برای چک با سررسید {date} هنوز اطلاعات ثبت چک "
|
||||
"(شمارهٔ صیادی) در سامانه ثبت نشده است. لطفاً نسبت به ثبت آن اقدام فرمایید.",
|
||||
)
|
||||
|
||||
# سایر انواع: هیچ فیلد زمانی نباید مقدار داشته باشد.
|
||||
SMSTemplate.objects.filter(
|
||||
sms_type__in=["welcome", "debt_due", "custom"],
|
||||
).update(offset_days=0, repeat_interval_days=None, repeat_interval_months=None)
|
||||
|
||||
|
||||
def noop(apps, schema_editor):
|
||||
pass
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("admin_panel", "0060_sms_permission_label"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="customer",
|
||||
name="sms_primary_phones",
|
||||
field=models.CharField(
|
||||
blank=True, default="", max_length=100,
|
||||
verbose_name="شمارههای اصلی پیامک",
|
||||
help_text="شمارههای نرمالشده (+98…) جداشده با کاما؛ خالی = شمارهٔ اول مشتری.",
|
||||
),
|
||||
),
|
||||
# ترتیب مهم است: ابتدا مقادیر فعلی خوانده و منتقل میشوند، سپس ستون قدیمی حذف میگردد.
|
||||
migrations.RunPython(backfill_primary_phones, noop),
|
||||
migrations.RemoveField(model_name="phonenumber", name="is_primary"),
|
||||
migrations.AddField(
|
||||
model_name="smstemplate",
|
||||
name="repeat_interval_months",
|
||||
field=models.PositiveSmallIntegerField(
|
||||
blank=True, null=True,
|
||||
verbose_name="دورهٔ تکرار (ماه)",
|
||||
help_text="برای «یادآوری بازدید»: چند ماه یکبار بازدید تکرار شود. "
|
||||
"خالی = پیشفرض سامانه (۹ ماه).",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="smstemplate",
|
||||
name="offset_days",
|
||||
field=models.PositiveSmallIntegerField(
|
||||
default=0,
|
||||
verbose_name="فاصلهٔ زمانی (روز)",
|
||||
help_text="معنای این عدد برای هر نوع پیامک متفاوت است و در پنل توضیح داده "
|
||||
"میشود؛ مثلاً «چند روز قبل از سررسید» یا «چند روز بعد از صدور فاکتور».",
|
||||
),
|
||||
),
|
||||
migrations.RunPython(normalize_template_timing, noop),
|
||||
]
|
||||
Reference in new issue
Block a user