232 lines
5.8 KiB
Python
232 lines
5.8 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
from typing import List, Optional
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
class PartnerReferrerItem(BaseModel):
|
|
id: int
|
|
telegram_id: int
|
|
username: Optional[str] = None
|
|
first_name: Optional[str] = None
|
|
last_name: Optional[str] = None
|
|
referral_code: Optional[str] = None
|
|
referral_commission_percent: Optional[int] = None
|
|
effective_referral_commission_percent: int
|
|
invited_count: int
|
|
active_referrals: int
|
|
total_earned_kopeks: int
|
|
total_earned_rubles: float
|
|
month_earned_kopeks: int
|
|
month_earned_rubles: float
|
|
created_at: datetime
|
|
last_activity: Optional[datetime] = None
|
|
|
|
|
|
class PartnerReferrerListResponse(BaseModel):
|
|
items: List[PartnerReferrerItem] = Field(default_factory=list)
|
|
total: int
|
|
limit: int
|
|
offset: int
|
|
|
|
|
|
class PartnerReferralItem(BaseModel):
|
|
id: int
|
|
telegram_id: int
|
|
full_name: str
|
|
username: Optional[str] = None
|
|
created_at: datetime
|
|
last_activity: Optional[datetime] = None
|
|
has_made_first_topup: bool
|
|
balance_kopeks: int
|
|
balance_rubles: float
|
|
total_earned_kopeks: int
|
|
total_earned_rubles: float
|
|
topups_count: int
|
|
days_since_registration: int
|
|
days_since_activity: Optional[int] = None
|
|
status: str
|
|
|
|
|
|
class PartnerReferralList(BaseModel):
|
|
items: List[PartnerReferralItem] = Field(default_factory=list)
|
|
total: int
|
|
limit: int
|
|
offset: int
|
|
has_next: bool
|
|
has_prev: bool
|
|
current_page: int
|
|
total_pages: int
|
|
|
|
|
|
class PartnerReferrerDetail(BaseModel):
|
|
referrer: PartnerReferrerItem
|
|
referrals: PartnerReferralList
|
|
|
|
|
|
class PartnerReferralCommissionUpdate(BaseModel):
|
|
referral_commission_percent: Optional[int] = Field(
|
|
default=None,
|
|
ge=0,
|
|
le=100,
|
|
description="Индивидуальный процент реферальной комиссии для пользователя",
|
|
)
|
|
|
|
|
|
# ============================================================================
|
|
# РАСШИРЕННАЯ СТАТИСТИКА ПАРТНЁРОВ
|
|
# ============================================================================
|
|
|
|
|
|
class EarningsByPeriod(BaseModel):
|
|
"""Заработки по периодам."""
|
|
all_time_kopeks: int
|
|
year_kopeks: int
|
|
month_kopeks: int
|
|
week_kopeks: int
|
|
today_kopeks: int
|
|
|
|
|
|
class ReferralsCountByPeriod(BaseModel):
|
|
"""Количество рефералов по периодам."""
|
|
all_time: int
|
|
year: int
|
|
month: int
|
|
week: int
|
|
today: int
|
|
|
|
|
|
class ReferrerSummary(BaseModel):
|
|
"""Сводка по рефереру."""
|
|
total_referrals: int
|
|
paid_referrals: int
|
|
active_referrals: int
|
|
conversion_to_paid_percent: float
|
|
conversion_to_active_percent: float
|
|
avg_earnings_per_referral_kopeks: float
|
|
|
|
|
|
class ReferrerDetailedStats(BaseModel):
|
|
"""Детальная статистика реферера."""
|
|
user_id: int
|
|
summary: ReferrerSummary
|
|
earnings: EarningsByPeriod
|
|
referrals_count: ReferralsCountByPeriod
|
|
|
|
|
|
class DailyStats(BaseModel):
|
|
"""Статистика за день."""
|
|
date: str
|
|
referrals_count: int
|
|
earnings_kopeks: int
|
|
|
|
|
|
class DailyStatsResponse(BaseModel):
|
|
"""Ответ со статистикой по дням."""
|
|
items: List[DailyStats]
|
|
days: int
|
|
user_id: Optional[int] = None
|
|
|
|
|
|
class TopReferralItem(BaseModel):
|
|
"""Топ реферал."""
|
|
id: int
|
|
telegram_id: int
|
|
username: Optional[str] = None
|
|
first_name: Optional[str] = None
|
|
last_name: Optional[str] = None
|
|
full_name: str
|
|
created_at: datetime
|
|
has_made_first_topup: bool
|
|
is_active: bool
|
|
total_earnings_kopeks: int
|
|
|
|
|
|
class TopReferralsResponse(BaseModel):
|
|
"""Топ рефералов реферера."""
|
|
items: List[TopReferralItem]
|
|
user_id: int
|
|
|
|
|
|
class PeriodData(BaseModel):
|
|
"""Данные за период."""
|
|
days: int
|
|
start: str
|
|
end: str
|
|
referrals_count: int
|
|
earnings_kopeks: int
|
|
|
|
|
|
class ChangeData(BaseModel):
|
|
"""Данные об изменении."""
|
|
absolute: int
|
|
percent: float
|
|
trend: str # up, down, stable
|
|
|
|
|
|
class PeriodChange(BaseModel):
|
|
"""Изменения между периодами."""
|
|
referrals: ChangeData
|
|
earnings: ChangeData
|
|
|
|
|
|
class PeriodComparisonResponse(BaseModel):
|
|
"""Сравнение периодов."""
|
|
current_period: PeriodData
|
|
previous_period: PeriodData
|
|
change: PeriodChange
|
|
user_id: Optional[int] = None
|
|
|
|
|
|
class GlobalPartnerSummary(BaseModel):
|
|
"""Глобальная сводка партнёрской программы."""
|
|
total_referrers: int
|
|
total_referrals: int
|
|
paid_referrals: int
|
|
conversion_rate_percent: float
|
|
avg_earnings_per_referral_kopeks: float
|
|
|
|
|
|
class PayoutsByPeriod(BaseModel):
|
|
"""Выплаты по периодам."""
|
|
all_time_kopeks: int
|
|
year_kopeks: int
|
|
month_kopeks: int
|
|
week_kopeks: int
|
|
today_kopeks: int
|
|
|
|
|
|
class NewReferralsByPeriod(BaseModel):
|
|
"""Новые рефералы по периодам."""
|
|
today: int
|
|
week: int
|
|
month: int
|
|
|
|
|
|
class GlobalPartnerStats(BaseModel):
|
|
"""Глобальная статистика партнёрской программы."""
|
|
summary: GlobalPartnerSummary
|
|
payouts: PayoutsByPeriod
|
|
new_referrals: NewReferralsByPeriod
|
|
|
|
|
|
class TopReferrerItem(BaseModel):
|
|
"""Топ реферер."""
|
|
id: int
|
|
telegram_id: int
|
|
username: Optional[str] = None
|
|
first_name: Optional[str] = None
|
|
last_name: Optional[str] = None
|
|
full_name: str
|
|
referral_code: Optional[str] = None
|
|
referrals_count: int
|
|
total_earnings_kopeks: int
|
|
|
|
|
|
class TopReferrersResponse(BaseModel):
|
|
"""Топ рефереров."""
|
|
items: List[TopReferrerItem]
|
|
days: Optional[int] = None
|