File size: 7,270 Bytes
efae096 d6be9e0 977d398 4835bd1 d6be9e0 4835bd1 efae096 977d398 d6be9e0 9fb60d3 66ac2af d6be9e0 664c52f d6be9e0 9fb60d3 49851a0 9fb60d3 66ac2af 9fb60d3 49851a0 4835bd1 49851a0 4835bd1 9fb60d3 4835bd1 d6be9e0 49851a0 9fb60d3 49851a0 9fb60d3 49851a0 9fb60d3 66ac2af 49851a0 66ac2af 9fb60d3 49851a0 9fb60d3 4835bd1 d6be9e0 9fb60d3 4835bd1 977d398 9fb60d3 66ac2af 977d398 903beee 6f10f85 a1ca4b8 977d398 efae096 a1ca4b8 9fb60d3 a1ca4b8 977d398 9fb60d3 977d398 66ac2af 6f10f85 977d398 9fb60d3 efae096 da630b4 6f10f85 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
import os
import stripe
import requests
import logging
import pytz
from fastapi import APIRouter, HTTPException, Header, Query
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
from typing import List, Dict, Any
router = APIRouter()
# Configuração das chaves do Stripe e Supabase
stripe.api_key = os.getenv("STRIPE_KEY")
stripe.api_version = "2023-10-16"
SUPABASE_URL = "https://ussxqnifefkgkaumjann.supabase.co"
SUPABASE_KEY = os.getenv("SUPA_KEY")
if not stripe.api_key or not SUPABASE_KEY:
raise ValueError("❌ STRIPE_KEY ou SUPA_KEY não foram definidos no ambiente!")
SUPABASE_HEADERS = {
"apikey": SUPABASE_KEY,
"Authorization": f"Bearer {SUPABASE_KEY}",
"Content-Type": "application/json"
}
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def verify_token(user_token: str) -> str:
headers = {
"Authorization": f"Bearer {user_token}",
"apikey": SUPABASE_KEY,
"Content-Type": "application/json"
}
response = requests.get(f"{SUPABASE_URL}/auth/v1/user", headers=headers)
if response.status_code == 200:
user_data = response.json()
user_id = user_data.get("id")
if not user_id:
raise HTTPException(status_code=400, detail="Invalid token: User ID not found")
return user_id
else:
raise HTTPException(status_code=401, detail="Invalid or expired token")
def get_account_balance(account_id: str) -> Dict[str, Any]:
try:
balance = stripe.Balance.retrieve(stripe_account=account_id)
available_balance = next((b.amount for b in balance.available if b.currency.upper() == "BRL"), 0)
pending_balance = next((b.amount for b in balance.pending if b.currency.upper() == "BRL"), 0)
return {
"available_balance": available_balance,
"pending_balance": pending_balance,
"currency": "BRL"
}
except Exception as e:
logger.error(f"❌ Error getting account balance: {str(e)}")
return {"available_balance": 0, "pending_balance": 0, "currency": "BRL"}
def get_monthly_revenue(account_id: str) -> List[Dict[str, Any]]:
ny_timezone = pytz.timezone('America/New_York')
now_ny = datetime.now(ny_timezone)
monthly_data = {}
for i in range(6):
target_date = now_ny - relativedelta(months=i)
month_num = target_date.month
month_name = target_date.strftime('%b')
year = target_date.year
month_key = f"{year}-{month_num}"
monthly_data[month_key] = {
"month": month_num,
"name": month_name,
"current": (month_num == now_ny.month and year == now_ny.year),
"amount": 0,
"growth": {"status": "", "percentage": 0, "formatted": "0.0%"}
}
start_date = now_ny - relativedelta(months=12)
start_timestamp = int(start_date.timestamp())
try:
transfers = stripe.Transfer.list(
destination=account_id,
created={"gte": start_timestamp},
limit=100
)
for transfer in transfers.data:
transfer_date = datetime.fromtimestamp(transfer.created, ny_timezone)
month_key = f"{transfer_date.year}-{transfer_date.month}"
if month_key in monthly_data:
monthly_data[month_key]["amount"] += transfer.amount
result = list(monthly_data.values())
result.sort(key=lambda x: (now_ny.month - x["month"]) % 12)
for i in range(len(result)):
current_month_data = result[i]
prev_year_month_key = f"{now_ny.year - 1}-{current_month_data['month']}"
previous_amount = monthly_data.get(prev_year_month_key, {}).get("amount", 0)
current_amount = current_month_data["amount"]
if previous_amount > 0:
growth_percentage = ((current_amount - previous_amount) / previous_amount) * 100
else:
growth_percentage = 100 if current_amount > 0 else 0
current_month_data["growth"] = {
"status": "up" if growth_percentage > 0 else "down",
"percentage": round(growth_percentage, 1),
"formatted": f"{round(growth_percentage, 1)}%"
}
return result
except Exception as e:
logger.error(f"❌ Error getting monthly revenue: {str(e)}")
return list(monthly_data.values())
def get_active_subscribers(user_id: str, page: int) -> Dict[str, Any]:
limit = 30
offset = page * limit
url = f"{SUPABASE_URL}/rest/v1/Subscriptions?stylist_id=eq.{user_id}&active=eq.true&limit={limit}&offset={offset}"
response = requests.get(url, headers=SUPABASE_HEADERS)
if response.status_code == 200:
subscribers = response.json()
subscriber_list = []
for sub in subscribers:
customer_id = sub.get("customer_id")
user_data_url = f"{SUPABASE_URL}/rest/v1/User?id=eq.{customer_id}"
user_response = requests.get(user_data_url, headers=SUPABASE_HEADERS)
if user_response.status_code == 200 and user_response.json():
user_info = user_response.json()[0]
subscriber_list.append({
"id": user_info.get("id"),
"name": user_info.get("name"),
"avatar": user_info.get("avatar"),
"blurhash": user_info.get("blurhash")
})
has_next_page = len(subscribers) == limit
return {"subscribers": subscriber_list, "has_next_page": has_next_page}
return {"subscribers": [], "has_next_page": False}
def get_total_followers(user_id: str) -> int:
url = f"{SUPABASE_URL}/rest/v1/followers?following_id=eq.{user_id}"
response = requests.get(url, headers=SUPABASE_HEADERS)
if response.status_code == 200:
followers = response.json()
return len(followers)
return 0
def get_total_subscribers(user_id: str) -> int:
url = f"{SUPABASE_URL}/rest/v1/Subscriptions?stylist_id=eq.{user_id}&active=eq.true"
response = requests.get(url, headers=SUPABASE_HEADERS)
if response.status_code == 200:
subscribers = response.json()
return len(subscribers)
return 0
@router.get("/dashboard")
def get_dashboard(user_token: str = Header(None, alias="User-key"), page: int = Query(0, ge=0)):
try:
user_id = verify_token(user_token)
user_data_url = f"{SUPABASE_URL}/rest/v1/User?id=eq.{user_id}"
response = requests.get(user_data_url, headers=SUPABASE_HEADERS)
user_data = response.json()[0]
stripe_id = user_data.get("stripe_id")
return {
"stripe_id": stripe_id,
"available_balance": get_account_balance(stripe_id),
"monthly_revenue": get_monthly_revenue(stripe_id),
"total_followers": get_total_followers(user_id),
"total_subscribers": get_total_subscribers(user_id),
**get_active_subscribers(user_id, page)
}
except Exception as e:
logger.error(f"❌ Error: {str(e)}")
raise HTTPException(status_code=500, detail=str(e)) |