fix: user card open in payments list for email only users

This commit is contained in:
3252a8
2026-05-12 23:53:35 +03:00
parent defbac43d7
commit e21a0758c3
5 changed files with 31 additions and 15 deletions
+23 -5
View File
@@ -262,14 +262,34 @@ def _payment_traffic_gb_split(payment: Payment) -> Tuple[Optional[float], Option
return None, None
def _payment_user_display_label(loaded_user: Any, payment_user_id: int) -> str:
"""Human-facing name for payments tables: TG profile name, else email, else user id."""
if loaded_user is None:
return str(payment_user_id)
tid = getattr(loaded_user, "telegram_id", None)
if tid is not None:
fn = (getattr(loaded_user, "first_name", None) or "").strip()
ln = (getattr(loaded_user, "last_name", None) or "").strip()
full = f"{fn} {ln}".strip()
if full:
return full
un = (getattr(loaded_user, "username", None) or "").strip()
if un:
return un if un.startswith("@") else f"@{un}"
return str(payment_user_id)
email = (getattr(loaded_user, "email", None) or "").strip()
if email:
return email
return str(payment_user_id)
def _serialize_payment(payment: Payment) -> Dict[str, Any]:
# Avoid lazy-loading `payment.user` outside an active SQLAlchemy session.
# Some admin routes serialize payments after the session scope is closed.
user_label = str(payment.user_id)
telegram_id = None
loaded_user = payment.__dict__.get("user")
user_label = _payment_user_display_label(loaded_user, int(payment.user_id))
if loaded_user is not None:
user_label = loaded_user.username or loaded_user.first_name or str(payment.user_id)
tid = getattr(loaded_user, "telegram_id", None)
if tid is not None:
try:
@@ -1550,9 +1570,7 @@ async def admin_payments_export_route(request: web.Request) -> web.Response:
]
)
for p in rows:
label = ""
if p.user:
label = p.user.username or p.user.first_name or ""
label = _payment_user_display_label(p.user, int(p.user_id)) if p.user else str(p.user_id)
writer.writerow(
[
p.payment_id,
@@ -262,7 +262,8 @@
function openPaymentUserCard(userId) {
const uid = Number(userId);
if (!Number.isFinite(uid) || uid <= 0) return;
// Synthetic email-only users use negative user_id; still a valid admin target.
if (!Number.isFinite(uid) || uid === 0) return;
const next = normalizeSection("users");
sidebarOpen = false;
if (active !== next) {
@@ -72,7 +72,7 @@
$: paymentHeaders = [
at("id", {}, "ID"),
at("user", {}, "Пользователь"),
at("payments_col_telegram_id", {}, "Telegram ID"),
at("payments_col_user_id", {}, "ID"),
at("payments_col_traffic_regular", {}, "Основной трафик"),
at("payments_col_traffic_premium", {}, "Премиум"),
at("amount", {}, "Сумма"),
@@ -104,7 +104,7 @@
<tr>
<th>{at("id", {}, "ID")}</th>
<th>{at("user", {}, "Пользователь")}</th>
<th>{at("payments_col_telegram_id", {}, "Telegram ID")}</th>
<th>{at("payments_col_user_id", {}, "ID")}</th>
<th>{at("payments_col_traffic_regular", {}, "Основной трафик")}</th>
<th>{at("payments_col_traffic_premium", {}, "Премиум")}</th>
<th>{at("amount", {}, "Сумма")}</th>
@@ -133,11 +133,8 @@
<span class="admin-payments-user-name">{p.user_label || p.user_id}</span>
</span>
</td>
<td
class="admin-cell-mono"
data-label={at("payments_col_telegram_id", {}, "Telegram ID")}
>
{p.telegram_id != null ? p.telegram_id : "—"}
<td class="admin-cell-mono" data-label={at("payments_col_user_id", {}, "ID")}>
{p.user_id != null && p.user_id !== "" ? p.user_id : "—"}
</td>
<td
class="admin-cell-traffic-gb"
+1 -1
View File
@@ -920,7 +920,7 @@
"admin_status": "Status",
"admin_date": "Date",
"admin_payments_empty": "No payments",
"admin_payments_col_telegram_id": "Telegram ID",
"admin_payments_col_user_id": "ID",
"admin_payments_col_traffic_regular": "Main traffic",
"admin_payments_col_traffic_premium": "Premium traffic",
"admin_payments_col_actions": "",
+1 -1
View File
@@ -920,7 +920,7 @@
"admin_status": "Статус",
"admin_date": "Дата",
"admin_payments_empty": "Нет платежей",
"admin_payments_col_telegram_id": "Telegram ID",
"admin_payments_col_user_id": "ID",
"admin_payments_col_traffic_regular": "Основной трафик",
"admin_payments_col_traffic_premium": "Премиум трафик",
"admin_payments_col_actions": "",