56 lines
2.0 KiB
Python
56 lines
2.0 KiB
Python
"""رندر قالب متن پیامک با placeholderهای امن."""
|
|
from persiantools.jdatetime import JalaliDate, JalaliDateTime
|
|
|
|
|
|
class _SafeDict(dict):
|
|
"""دیکشنری امن برای ``str.format_map``.
|
|
|
|
* کلیدِ ناشناخته ⇒ رشتهٔ خالی (بدون ``KeyError``).
|
|
* کلیدِ شناختهشده با مقدار ``None`` ⇒ رشتهٔ خالی. فیلدهای اختیاری مدل
|
|
(مثل ``Sarresid.check_sayyad_id`` یا ``check_row_number``) ممکن است ``NULL``
|
|
باشند؛ بدون این تبدیل، ``None`` عیناً در متن پیامک چاپ میشد.
|
|
"""
|
|
|
|
def __missing__(self, key):
|
|
return ""
|
|
|
|
def __getitem__(self, key):
|
|
value = super().__getitem__(key) if key in self else ""
|
|
return "" if value is None else value
|
|
|
|
|
|
def format_amount(value):
|
|
try:
|
|
return f"{int(value):,}"
|
|
except (TypeError, ValueError):
|
|
return str(value or "")
|
|
|
|
|
|
def format_jalali(value):
|
|
"""تبدیل datetime/date به تاریخ جلالی ``YYYY/MM/DD``."""
|
|
if not value:
|
|
return ""
|
|
try:
|
|
if hasattr(value, "date") and callable(getattr(value, "date")):
|
|
value = value.date()
|
|
return JalaliDate(value).strftime("%Y/%m/%d")
|
|
except Exception:
|
|
try:
|
|
return JalaliDateTime(value).strftime("%Y/%m/%d")
|
|
except Exception:
|
|
return str(value)
|
|
|
|
|
|
def render_template(text, context=None):
|
|
ctx = dict(context or {})
|
|
if "amount" in ctx:
|
|
ctx.setdefault("amount_sep", format_amount(ctx["amount"]))
|
|
if "balance" in ctx:
|
|
# مثل «مبلغ»، نسخهٔ جداکنندهدار هم آماده میشود تا در قالبها
|
|
# ``{balance_sep}`` در دسترس باشد (۳٬۵۰۰٬۰۰۰ → "3,500,000").
|
|
ctx.setdefault("balance_sep", format_amount(ctx["balance"]))
|
|
if "date" in ctx:
|
|
ctx.setdefault("date_raw", ctx["date"])
|
|
ctx["date"] = format_jalali(ctx["date"])
|
|
return (text or "").format_map(_SafeDict(ctx))
|