Spaces:
Running on Zero
Running on Zero
Commit ·
0af87ef
1
Parent(s): 1b5947e
fix(tier): require active, non-revoked, and non-expired subscription for pro/vip tiers
Browse files- app/superadmin_routes.py +111 -38
app/superadmin_routes.py
CHANGED
|
@@ -610,47 +610,97 @@ async def get_all_users(
|
|
| 610 |
|
| 611 |
if tier and tier.strip() and tier.strip().upper() != "ALL":
|
| 612 |
t = tier.strip().upper().replace(" ", "_")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 613 |
if t in ("20_ADFREE", "AD_FREE", "ADFREE", "20"):
|
| 614 |
tier_clause = {
|
| 615 |
-
"$
|
| 616 |
-
|
| 617 |
-
|
| 618 |
-
{
|
| 619 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 620 |
]
|
| 621 |
}
|
| 622 |
-
elif t in ("
|
| 623 |
tier_clause = {
|
| 624 |
-
"$
|
| 625 |
-
|
| 626 |
-
|
| 627 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 628 |
]
|
| 629 |
}
|
| 630 |
-
elif t in ("
|
| 631 |
tier_clause = {
|
| 632 |
-
"$
|
| 633 |
-
|
| 634 |
-
|
| 635 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 636 |
]
|
| 637 |
}
|
| 638 |
-
elif t in ("
|
| 639 |
tier_clause = {
|
| 640 |
-
"$
|
| 641 |
-
|
| 642 |
-
|
| 643 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 644 |
]
|
| 645 |
}
|
| 646 |
-
elif t in ("
|
| 647 |
tier_clause = {
|
| 648 |
-
"$
|
| 649 |
-
|
| 650 |
-
|
| 651 |
-
|
| 652 |
-
{
|
| 653 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 654 |
]
|
| 655 |
}
|
| 656 |
else:
|
|
@@ -786,24 +836,47 @@ async def get_all_users(
|
|
| 786 |
# Canonical tier resolution across the 5 tiers:
|
| 787 |
# 20 adfree, 159 pro, 800 pro, 1500 pro, vip pro (or FREE)
|
| 788 |
sub = u.get("subscription") if isinstance(u.get("subscription"), dict) else {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 789 |
plan_id = str(sub.get("plan_id") or "").lower()
|
| 790 |
tag = str(sub.get("tag") or "").lower()
|
| 791 |
pay_method = str(sub.get("payment_method") or "").lower()
|
| 792 |
tier_val = str(sub.get("tier") or "").upper()
|
| 793 |
amt = float(sub.get("amount") or u.get("amount") or 0.0)
|
| 794 |
-
is_pro = bool(u.get("is_pro") or sub.get("is_pro", False))
|
| 795 |
-
is_ad_free = bool(u.get("is_ad_free_admob") or "ad_free" in plan_id or tier_val == "AD_FREE")
|
| 796 |
|
| 797 |
resolved_tier = "FREE"
|
| 798 |
-
if
|
| 799 |
-
|
| 800 |
-
|
| 801 |
-
|
| 802 |
-
|
| 803 |
-
|
| 804 |
-
|
| 805 |
-
|
| 806 |
-
|
|
|
|
| 807 |
resolved_tier = "20_ADFREE"
|
| 808 |
|
| 809 |
u["tier"] = resolved_tier
|
|
|
|
| 610 |
|
| 611 |
if tier and tier.strip() and tier.strip().upper() != "ALL":
|
| 612 |
t = tier.strip().upper().replace(" ", "_")
|
| 613 |
+
now_dt = datetime.datetime.utcnow()
|
| 614 |
+
not_revoked_clause = {
|
| 615 |
+
"subscription.status": {"$nin": ["REVOKED", "CANCELLED", "EXPIRED", "revoked", "cancelled", "expired"]}
|
| 616 |
+
}
|
| 617 |
+
not_expired_clause = {
|
| 618 |
+
"$or": [
|
| 619 |
+
{"subscription.expires_at": None},
|
| 620 |
+
{"subscription.expires_at": {"$gte": now_dt}},
|
| 621 |
+
{"subscription.expires_at": {"$exists": False}},
|
| 622 |
+
]
|
| 623 |
+
}
|
| 624 |
+
pro_active_clause = {
|
| 625 |
+
"$or": [{"is_pro": True}, {"subscription.is_pro": True}]
|
| 626 |
+
}
|
| 627 |
+
|
| 628 |
if t in ("20_ADFREE", "AD_FREE", "ADFREE", "20"):
|
| 629 |
tier_clause = {
|
| 630 |
+
"$and": [
|
| 631 |
+
not_revoked_clause,
|
| 632 |
+
not_expired_clause,
|
| 633 |
+
{
|
| 634 |
+
"$or": [
|
| 635 |
+
{"is_ad_free_admob": True},
|
| 636 |
+
{"subscription.plan_id": "sahih_ad_free_monthly"},
|
| 637 |
+
{"subscription.amount": 20.0},
|
| 638 |
+
{"subscription.tier": "AD_FREE"},
|
| 639 |
+
]
|
| 640 |
+
}
|
| 641 |
]
|
| 642 |
}
|
| 643 |
+
elif t in ("VIP_PRO", "VIP", "VIP_OFFER"):
|
| 644 |
tier_clause = {
|
| 645 |
+
"$and": [
|
| 646 |
+
pro_active_clause,
|
| 647 |
+
not_revoked_clause,
|
| 648 |
+
not_expired_clause,
|
| 649 |
+
{
|
| 650 |
+
"$or": [
|
| 651 |
+
{"subscription.tag": "VIP offer"},
|
| 652 |
+
{"subscription.payment_method": "VIP offer"},
|
| 653 |
+
{"subscription.plan_id": {"$in": ["vip_pro", "vip_offer", "pro_lifetime"]}},
|
| 654 |
+
{"subscription.tier": "VIP_PRO"},
|
| 655 |
+
{"is_vip": True},
|
| 656 |
+
]
|
| 657 |
+
}
|
| 658 |
]
|
| 659 |
}
|
| 660 |
+
elif t in ("1500_PRO", "PRO_ANNUAL", "1500"):
|
| 661 |
tier_clause = {
|
| 662 |
+
"$and": [
|
| 663 |
+
pro_active_clause,
|
| 664 |
+
not_revoked_clause,
|
| 665 |
+
not_expired_clause,
|
| 666 |
+
{
|
| 667 |
+
"$or": [
|
| 668 |
+
{"subscription.plan_id": "sahih_pro_annual"},
|
| 669 |
+
{"subscription.amount": 1500.0},
|
| 670 |
+
{"subscription.tier": "1500_PRO"},
|
| 671 |
+
]
|
| 672 |
+
}
|
| 673 |
]
|
| 674 |
}
|
| 675 |
+
elif t in ("800_PRO", "PRO_6MONTH", "800"):
|
| 676 |
tier_clause = {
|
| 677 |
+
"$and": [
|
| 678 |
+
pro_active_clause,
|
| 679 |
+
not_revoked_clause,
|
| 680 |
+
not_expired_clause,
|
| 681 |
+
{
|
| 682 |
+
"$or": [
|
| 683 |
+
{"subscription.plan_id": "sahih_pro_6month"},
|
| 684 |
+
{"subscription.amount": 800.0},
|
| 685 |
+
{"subscription.tier": "800_PRO"},
|
| 686 |
+
]
|
| 687 |
+
}
|
| 688 |
]
|
| 689 |
}
|
| 690 |
+
elif t in ("159_PRO", "PRO_MONTHLY", "159"):
|
| 691 |
tier_clause = {
|
| 692 |
+
"$and": [
|
| 693 |
+
pro_active_clause,
|
| 694 |
+
not_revoked_clause,
|
| 695 |
+
not_expired_clause,
|
| 696 |
+
{
|
| 697 |
+
"$or": [
|
| 698 |
+
{"subscription.plan_id": "sahih_pro_monthly"},
|
| 699 |
+
{"subscription.amount": 159.0},
|
| 700 |
+
{"subscription.tier": "159_PRO"},
|
| 701 |
+
{"subscription.tier": "PRO"},
|
| 702 |
+
]
|
| 703 |
+
}
|
| 704 |
]
|
| 705 |
}
|
| 706 |
else:
|
|
|
|
| 836 |
# Canonical tier resolution across the 5 tiers:
|
| 837 |
# 20 adfree, 159 pro, 800 pro, 1500 pro, vip pro (or FREE)
|
| 838 |
sub = u.get("subscription") if isinstance(u.get("subscription"), dict) else {}
|
| 839 |
+
sub_status = str(sub.get("status") or "").upper()
|
| 840 |
+
is_revoked = sub_status in ("REVOKED", "CANCELLED", "EXPIRED")
|
| 841 |
+
|
| 842 |
+
is_expired = False
|
| 843 |
+
expires_at = sub.get("expires_at")
|
| 844 |
+
if expires_at:
|
| 845 |
+
try:
|
| 846 |
+
if isinstance(expires_at, str):
|
| 847 |
+
exp_dt = datetime.datetime.fromisoformat(expires_at.replace("Z", "+00:00"))
|
| 848 |
+
elif isinstance(expires_at, datetime.datetime):
|
| 849 |
+
exp_dt = expires_at
|
| 850 |
+
else:
|
| 851 |
+
exp_dt = None
|
| 852 |
+
if exp_dt:
|
| 853 |
+
if exp_dt.tzinfo is not None:
|
| 854 |
+
exp_dt = exp_dt.astimezone(datetime.timezone.utc).replace(tzinfo=None)
|
| 855 |
+
if exp_dt < datetime.datetime.utcnow():
|
| 856 |
+
is_expired = True
|
| 857 |
+
except Exception:
|
| 858 |
+
pass
|
| 859 |
+
|
| 860 |
+
is_pro_active = (bool(u.get("is_pro")) or bool(sub.get("is_pro"))) and not is_revoked and not is_expired
|
| 861 |
+
is_ad_free_active = bool(u.get("is_ad_free_admob")) and not is_revoked and not is_expired
|
| 862 |
+
|
| 863 |
plan_id = str(sub.get("plan_id") or "").lower()
|
| 864 |
tag = str(sub.get("tag") or "").lower()
|
| 865 |
pay_method = str(sub.get("payment_method") or "").lower()
|
| 866 |
tier_val = str(sub.get("tier") or "").upper()
|
| 867 |
amt = float(sub.get("amount") or u.get("amount") or 0.0)
|
|
|
|
|
|
|
| 868 |
|
| 869 |
resolved_tier = "FREE"
|
| 870 |
+
if is_pro_active:
|
| 871 |
+
if "vip" in tag or "vip" in pay_method or "vip" in plan_id or u.get("is_vip") or tier_val in ("VIP", "VIP_PRO"):
|
| 872 |
+
resolved_tier = "VIP_PRO"
|
| 873 |
+
elif plan_id == "sahih_pro_annual" or "annual" in plan_id or amt == 1500.0 or tier_val in ("1500_PRO", "ANNUAL"):
|
| 874 |
+
resolved_tier = "1500_PRO"
|
| 875 |
+
elif plan_id == "sahih_pro_6month" or "6month" in plan_id or amt == 800.0 or tier_val in ("800_PRO",):
|
| 876 |
+
resolved_tier = "800_PRO"
|
| 877 |
+
else:
|
| 878 |
+
resolved_tier = "159_PRO"
|
| 879 |
+
elif is_ad_free_active or (("ad_free" in plan_id or amt == 20.0 or tier_val == "AD_FREE") and not is_revoked and not is_expired):
|
| 880 |
resolved_tier = "20_ADFREE"
|
| 881 |
|
| 882 |
u["tier"] = resolved_tier
|