"""رندر قالب متن پیامک با 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))