Добавлено новое поле promocode в модель StatReferralsItem и модель Ref. Обновлены функции в fill_db.py для генерации уникальных промокодов при создании реферальных ссылок. Обновлены эндпоинты в integration_api.py для возврата промокодов вместе с реферальными ссылками. Удалены устаревшие функции работы с промокодами из кода. Обновлены SQL-скрипты и модели для учета новых полей.
This commit is contained in:
parent
92df59ad23
commit
d113ae4adb
@ -89,6 +89,7 @@ class StatReferralsItem(BaseModel):
|
|||||||
ref: str
|
ref: str
|
||||||
agent: Optional[str] = None
|
agent: Optional[str] = None
|
||||||
description: str
|
description: str
|
||||||
|
promocode: str
|
||||||
salesSum: float
|
salesSum: float
|
||||||
salesCount: int
|
salesCount: int
|
||||||
|
|
||||||
|
|||||||
36
fill_db.py
36
fill_db.py
@ -1,7 +1,7 @@
|
|||||||
import random
|
import random
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
from sqlmodel import Session
|
from sqlmodel import Session
|
||||||
from sql_models import TgAgent, Ref, Sale, Account, Company, AgentTransaction, PartnerTransaction, CompanyBalance, AgentBalance, IntegrationToken, PromoCode
|
from sql_models import TgAgent, Ref, Sale, Account, Company, AgentTransaction, PartnerTransaction, CompanyBalance, AgentBalance, IntegrationToken
|
||||||
from sqlalchemy import text
|
from sqlalchemy import text
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from hashlib import sha256
|
from hashlib import sha256
|
||||||
@ -72,7 +72,7 @@ def fill_db():
|
|||||||
date_list = get_date_list(7) # 8 дней: от недели назад до сегодня
|
date_list = get_date_list(7) # 8 дней: от недели назад до сегодня
|
||||||
with Session(AUTH_DB_ENGINE) as session:
|
with Session(AUTH_DB_ENGINE) as session:
|
||||||
# Очистка таблиц
|
# Очистка таблиц
|
||||||
session.execute(text("DELETE FROM promocode"))
|
# session.execute(text("DELETE FROM promocode"))
|
||||||
session.execute(text("DELETE FROM sale"))
|
session.execute(text("DELETE FROM sale"))
|
||||||
session.execute(text("DELETE FROM ref"))
|
session.execute(text("DELETE FROM ref"))
|
||||||
session.execute(text("DELETE FROM tgagent"))
|
session.execute(text("DELETE FROM tgagent"))
|
||||||
@ -154,45 +154,25 @@ def fill_db():
|
|||||||
# Отладка: количество агентов
|
# Отладка: количество агентов
|
||||||
agent_count = session.execute(text("SELECT COUNT(*) FROM tgagent")).scalar()
|
agent_count = session.execute(text("SELECT COUNT(*) FROM tgagent")).scalar()
|
||||||
print(f'Агентов в базе: {agent_count}')
|
print(f'Агентов в базе: {agent_count}')
|
||||||
# Генерация промокодов для каждого агента с try/except
|
|
||||||
alphabet = string.ascii_letters + string.digits + "!@#$%^&*"
|
|
||||||
try:
|
|
||||||
for tg_agent in tg_agents:
|
|
||||||
promocode_count = random.randint(2, 4)
|
|
||||||
for _ in range(promocode_count):
|
|
||||||
promocode = ''.join(random.choices(alphabet, k=8))
|
|
||||||
# Проверяем уникальность
|
|
||||||
while session.execute(text("SELECT 1 FROM promocode WHERE promocode = :code"), {"code": promocode}).first():
|
|
||||||
promocode = ''.join(random.choices(alphabet, k=8))
|
|
||||||
promo = PromoCode(
|
|
||||||
promocode=promocode,
|
|
||||||
perc=10.0,
|
|
||||||
agent_id=tg_agent.id,
|
|
||||||
description=random.choice(DESCRIPTIONS),
|
|
||||||
create_dttm=datetime.utcnow(),
|
|
||||||
update_dttm=datetime.utcnow()
|
|
||||||
)
|
|
||||||
session.add(promo)
|
|
||||||
session.commit()
|
|
||||||
except Exception as e:
|
|
||||||
print(f'Ошибка при добавлении промокодов: {e}')
|
|
||||||
session.rollback()
|
|
||||||
# Отладка: количество промокодов
|
|
||||||
count = session.execute(text("SELECT COUNT(*) FROM promocode")).scalar()
|
|
||||||
print(f'Промокодов в базе: {count}')
|
|
||||||
# 3. Refs (минимум 22 на агента)
|
# 3. Refs (минимум 22 на агента)
|
||||||
refs = []
|
refs = []
|
||||||
desc_count = len(ALL_DESCRIPTIONS)
|
desc_count = len(ALL_DESCRIPTIONS)
|
||||||
|
alphabet = string.ascii_letters + string.digits + "!@#$%^&*"
|
||||||
for tg_agent in tg_agents:
|
for tg_agent in tg_agents:
|
||||||
ref_count = random.randint(22, int(22 * 1.25)) # от 22 до 27
|
ref_count = random.randint(22, int(22 * 1.25)) # от 22 до 27
|
||||||
for j in range(ref_count):
|
for j in range(ref_count):
|
||||||
ref_val = str(uuid4())
|
ref_val = str(uuid4())
|
||||||
desc_val = ALL_DESCRIPTIONS[(j % desc_count)]
|
desc_val = ALL_DESCRIPTIONS[(j % desc_count)]
|
||||||
dt = random.choice(date_list)
|
dt = random.choice(date_list)
|
||||||
|
promocode = ''.join(random.choices(alphabet, k=8))
|
||||||
|
# Проверяем уникальность промокода среди уже созданных рефов
|
||||||
|
while any(r.promocode == promocode for r in refs):
|
||||||
|
promocode = ''.join(random.choices(alphabet, k=8))
|
||||||
ref = Ref(
|
ref = Ref(
|
||||||
tg_agent_id=tg_agent.id,
|
tg_agent_id=tg_agent.id,
|
||||||
ref=ref_val,
|
ref=ref_val,
|
||||||
description=desc_val,
|
description=desc_val,
|
||||||
|
promocode=promocode,
|
||||||
create_dttm=dt,
|
create_dttm=dt,
|
||||||
update_dttm=dt
|
update_dttm=dt
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
from sqlmodel import SQLModel
|
from sqlmodel import SQLModel
|
||||||
from sql_models import Company, TgAgent, Ref, Sale, AgentTransaction, PartnerTransaction, CompanyBalance, AgentBalance, Account, IntegrationToken, PromoCode
|
|
||||||
from helpers_bff import AUTH_DB_ENGINE
|
from helpers_bff import AUTH_DB_ENGINE
|
||||||
from sqlalchemy.schema import CreateTable
|
from sqlalchemy.schema import CreateTable
|
||||||
import os
|
import os
|
||||||
|
|||||||
@ -7,10 +7,10 @@ import uuid
|
|||||||
from random import choices
|
from random import choices
|
||||||
import string
|
import string
|
||||||
|
|
||||||
from sql_models import Company, IntegrationToken, Ref, Sale, AgentTransaction, PartnerTransaction, AgentBalance, TgAgent, CompanyBalance, PromoCode
|
from sql_models import Company, IntegrationToken, Ref, Sale, AgentTransaction, PartnerTransaction, AgentBalance, TgAgent, CompanyBalance
|
||||||
from integration_models import Token, SaleCreateRequest, SaleCreateResponse, TransactionStatus, WithdrawRequest, WithdrawResponse
|
from integration_models import Token, SaleCreateRequest, SaleCreateResponse, TransactionStatus, WithdrawRequest, WithdrawResponse
|
||||||
from bff_models import RegisterResponse, TgAuthResponse
|
from bff_models import RegisterResponse, TgAuthResponse
|
||||||
from tg_models import RefAddRequest, RefResponse, RefAddResponse, RefStatResponse, RegisterRequest, StatResponse, PromoCodeAddRequest, PromoCodeResponse
|
from tg_models import RefAddRequest, RefResponse, RefAddResponse, RefStatResponse, RegisterRequest, StatResponse
|
||||||
from helpers_bff import AUTH_DB_ENGINE, get_integration_db, create_integration_jwt_token, get_current_company_from_jwt, get_tg_agent_by_tg_id, get_current_tg_agent
|
from helpers_bff import AUTH_DB_ENGINE, get_integration_db, create_integration_jwt_token, get_current_company_from_jwt, get_tg_agent_by_tg_id, get_current_tg_agent
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
@ -61,22 +61,28 @@ def get_refs(current_tg_agent: TgAgent = Depends(get_current_tg_agent), db: Sess
|
|||||||
Возвращает список реферальных ссылок текущего Telegram-агента.
|
Возвращает список реферальных ссылок текущего Telegram-агента.
|
||||||
"""
|
"""
|
||||||
refs = db.exec(select(Ref).where(Ref.tg_agent_id == current_tg_agent.id)).all()
|
refs = db.exec(select(Ref).where(Ref.tg_agent_id == current_tg_agent.id)).all()
|
||||||
return [RefResponse(ref=r.ref, description=r.description or "") for r in refs]
|
return [RefResponse(ref=r.ref, description=r.description or "", promocode=r.promocode) for r in refs]
|
||||||
|
|
||||||
@app.post("/ref/add", tags=["agent-tg"], response_model=RefAddResponse)
|
@app.post("/ref/add", tags=["agent-tg"], response_model=RefAddResponse)
|
||||||
def add_ref(req: RefAddRequest, current_tg_agent: TgAgent = Depends(get_current_tg_agent), db: Session = Depends(get_integration_db)):
|
def add_ref(req: RefAddRequest, current_tg_agent: TgAgent = Depends(get_current_tg_agent), db: Session = Depends(get_integration_db)):
|
||||||
"""
|
"""
|
||||||
Добавляет новую реферальную ссылку для текущего Telegram-агента.
|
Добавляет новую реферальную ссылку для текущего Telegram-агента.
|
||||||
"""
|
"""
|
||||||
|
# Генерация промокода (логика как была для промокодов)
|
||||||
|
alphabet = string.ascii_letters + string.digits + "!@#$%^&*"
|
||||||
|
promocode = ''.join(choices(alphabet, k=8))
|
||||||
|
while db.exec(select(Ref).where(Ref.promocode == promocode)).first():
|
||||||
|
promocode = ''.join(choices(alphabet, k=8))
|
||||||
new_ref = Ref(
|
new_ref = Ref(
|
||||||
tg_agent_id=current_tg_agent.id,
|
tg_agent_id=current_tg_agent.id,
|
||||||
ref=str(uuid.uuid4()),
|
ref=str(uuid.uuid4()),
|
||||||
description=req.description
|
description=req.description,
|
||||||
|
promocode=promocode
|
||||||
)
|
)
|
||||||
db.add(new_ref)
|
db.add(new_ref)
|
||||||
db.commit()
|
db.commit()
|
||||||
db.refresh(new_ref)
|
db.refresh(new_ref)
|
||||||
return {"ref": new_ref.ref}
|
return {"ref": new_ref.ref, "promocode": new_ref.promocode, "description": new_ref.description}
|
||||||
|
|
||||||
@app.get("/ref/stat", tags=["agent-tg"], response_model=RefStatResponse)
|
@app.get("/ref/stat", tags=["agent-tg"], response_model=RefStatResponse)
|
||||||
def get_ref_stat(current_tg_agent: TgAgent = Depends(get_current_tg_agent), db: Session = Depends(get_integration_db)):
|
def get_ref_stat(current_tg_agent: TgAgent = Depends(get_current_tg_agent), db: Session = Depends(get_integration_db)):
|
||||||
@ -306,32 +312,3 @@ def register(req: RegisterRequest, db: Session = Depends(get_integration_db)):
|
|||||||
db.commit()
|
db.commit()
|
||||||
db.refresh(new_tg_agent)
|
db.refresh(new_tg_agent)
|
||||||
return {"msg": "TgAgent registered successfully"}
|
return {"msg": "TgAgent registered successfully"}
|
||||||
|
|
||||||
@app.post("/promocode/add", tags=["agent-tg"], response_model=PromoCodeResponse)
|
|
||||||
def add_promocode(req: PromoCodeAddRequest, current_tg_agent: TgAgent = Depends(get_current_tg_agent), db: Session = Depends(get_integration_db)):
|
|
||||||
"""
|
|
||||||
Создает новый промокод для текущего Telegram-агента.
|
|
||||||
"""
|
|
||||||
description = req.description
|
|
||||||
alphabet = string.ascii_letters + string.digits + "!@#$%^&*"
|
|
||||||
promocode = ''.join(choices(alphabet, k=8))
|
|
||||||
while db.exec(select(PromoCode).where(PromoCode.promocode == promocode)).first():
|
|
||||||
promocode = ''.join(choices(alphabet, k=8))
|
|
||||||
new_code = PromoCode(
|
|
||||||
promocode=promocode,
|
|
||||||
perc=10.0,
|
|
||||||
agent_id=current_tg_agent.id,
|
|
||||||
description=description
|
|
||||||
)
|
|
||||||
db.add(new_code)
|
|
||||||
db.commit()
|
|
||||||
db.refresh(new_code)
|
|
||||||
return PromoCodeResponse(promocode=new_code.promocode, perc=new_code.perc, description=new_code.description)
|
|
||||||
|
|
||||||
@app.get("/promocode", tags=["agent-tg"], response_model=List[PromoCodeResponse])
|
|
||||||
def get_promocodes(current_tg_agent: TgAgent = Depends(get_current_tg_agent), db: Session = Depends(get_integration_db)):
|
|
||||||
"""
|
|
||||||
Получает все промокоды текущего Telegram-агента.
|
|
||||||
"""
|
|
||||||
codes = db.exec(select(PromoCode).where(PromoCode.agent_id == current_tg_agent.id)).all()
|
|
||||||
return [PromoCodeResponse(promocode=c.promocode, perc=c.perc, description=c.description) for c in codes]
|
|
||||||
|
|||||||
1
main.py
1
main.py
@ -252,6 +252,7 @@ def get_referrals_stat(
|
|||||||
"ref": ref.ref,
|
"ref": ref.ref,
|
||||||
"agent": agent.name if agent and agent.name else f"Агент {ref.tg_agent_id}",
|
"agent": agent.name if agent and agent.name else f"Агент {ref.tg_agent_id}",
|
||||||
"description": ref.description or "",
|
"description": ref.description or "",
|
||||||
|
"promocode": ref.promocode,
|
||||||
"salesSum": sales_sum,
|
"salesSum": sales_sum,
|
||||||
"salesCount": sales_count
|
"salesCount": sales_count
|
||||||
})
|
})
|
||||||
|
|||||||
@ -110,26 +110,12 @@ CREATE TABLE agent_transactions (
|
|||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE promocode (
|
|
||||||
id INTEGER NOT NULL,
|
|
||||||
promocode VARCHAR NOT NULL,
|
|
||||||
perc FLOAT NOT NULL,
|
|
||||||
agent_id INTEGER NOT NULL,
|
|
||||||
description VARCHAR,
|
|
||||||
create_dttm DATETIME NOT NULL,
|
|
||||||
update_dttm DATETIME NOT NULL,
|
|
||||||
PRIMARY KEY (id),
|
|
||||||
FOREIGN KEY(agent_id) REFERENCES tgagent (id)
|
|
||||||
)
|
|
||||||
|
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE ref (
|
CREATE TABLE ref (
|
||||||
id INTEGER NOT NULL,
|
id INTEGER NOT NULL,
|
||||||
tg_agent_id INTEGER NOT NULL,
|
tg_agent_id INTEGER NOT NULL,
|
||||||
ref VARCHAR NOT NULL,
|
ref VARCHAR NOT NULL,
|
||||||
description VARCHAR,
|
description VARCHAR,
|
||||||
|
promocode VARCHAR(8) NOT NULL,
|
||||||
create_dttm DATETIME NOT NULL,
|
create_dttm DATETIME NOT NULL,
|
||||||
update_dttm DATETIME NOT NULL,
|
update_dttm DATETIME NOT NULL,
|
||||||
PRIMARY KEY (id),
|
PRIMARY KEY (id),
|
||||||
|
|||||||
@ -37,13 +37,13 @@ class TgAgent(SQLModel, table=True):
|
|||||||
refs: List["Ref"] = Relationship(back_populates="tg_agent")
|
refs: List["Ref"] = Relationship(back_populates="tg_agent")
|
||||||
agent_transactions: List["AgentTransaction"] = Relationship(back_populates="tg_agent")
|
agent_transactions: List["AgentTransaction"] = Relationship(back_populates="tg_agent")
|
||||||
agent_balance: Optional["AgentBalance"] = Relationship(back_populates="tg_agent")
|
agent_balance: Optional["AgentBalance"] = Relationship(back_populates="tg_agent")
|
||||||
promocodes: List["PromoCode"] = Relationship(back_populates="agent")
|
|
||||||
|
|
||||||
class Ref(SQLModel, table=True):
|
class Ref(SQLModel, table=True):
|
||||||
id: Optional[int] = Field(default=None, primary_key=True)
|
id: Optional[int] = Field(default=None, primary_key=True)
|
||||||
tg_agent_id: int = Field(foreign_key="tgagent.id")
|
tg_agent_id: int = Field(foreign_key="tgagent.id")
|
||||||
ref: str
|
ref: str
|
||||||
description: Optional[str] = None
|
description: Optional[str] = None
|
||||||
|
promocode: str = Field(index=True, unique=True, max_length=8)
|
||||||
create_dttm: datetime = Field(default_factory=datetime.utcnow)
|
create_dttm: datetime = Field(default_factory=datetime.utcnow)
|
||||||
update_dttm: datetime = Field(default_factory=datetime.utcnow)
|
update_dttm: datetime = Field(default_factory=datetime.utcnow)
|
||||||
|
|
||||||
@ -137,15 +137,4 @@ class IntegrationToken(SQLModel, table=True):
|
|||||||
update_dttm: datetime = Field(default_factory=datetime.utcnow, nullable=False)
|
update_dttm: datetime = Field(default_factory=datetime.utcnow, nullable=False)
|
||||||
use_dttm: Optional[datetime] = None
|
use_dttm: Optional[datetime] = None
|
||||||
|
|
||||||
company: "Company" = Relationship(back_populates="integration_tokens")
|
company: "Company" = Relationship(back_populates="integration_tokens")
|
||||||
|
|
||||||
class PromoCode(SQLModel, table=True):
|
|
||||||
id: Optional[int] = Field(default=None, primary_key=True)
|
|
||||||
promocode: str = Field(index=True, unique=True)
|
|
||||||
perc: float = Field(default=10.0)
|
|
||||||
agent_id: int = Field(foreign_key="tgagent.id")
|
|
||||||
description: Optional[str] = None
|
|
||||||
create_dttm: datetime = Field(default_factory=datetime.utcnow)
|
|
||||||
update_dttm: datetime = Field(default_factory=datetime.utcnow)
|
|
||||||
|
|
||||||
agent: "TgAgent" = Relationship(back_populates="promocodes")
|
|
||||||
13
tg_models.py
13
tg_models.py
@ -7,6 +7,7 @@ from uuid import UUID
|
|||||||
class RefResponse(BaseModel):
|
class RefResponse(BaseModel):
|
||||||
ref: str
|
ref: str
|
||||||
description: str
|
description: str
|
||||||
|
promocode: str
|
||||||
|
|
||||||
class RefAddRequest(BaseModel):
|
class RefAddRequest(BaseModel):
|
||||||
description: str
|
description: str
|
||||||
@ -25,6 +26,8 @@ class RegisterRequest(BaseModel):
|
|||||||
# New Response Models for TG APIs
|
# New Response Models for TG APIs
|
||||||
class RefAddResponse(BaseModel):
|
class RefAddResponse(BaseModel):
|
||||||
ref: str
|
ref: str
|
||||||
|
promocode: str
|
||||||
|
description: str
|
||||||
|
|
||||||
class RefStatItem(BaseModel):
|
class RefStatItem(BaseModel):
|
||||||
description: str
|
description: str
|
||||||
@ -37,12 +40,4 @@ class RefStatResponse(BaseModel):
|
|||||||
class StatResponse(BaseModel):
|
class StatResponse(BaseModel):
|
||||||
totalSales: int
|
totalSales: int
|
||||||
totalIncome: float
|
totalIncome: float
|
||||||
availableWithdrawal: float
|
availableWithdrawal: float
|
||||||
|
|
||||||
class PromoCodeAddRequest(BaseModel):
|
|
||||||
description: Optional[str] = None
|
|
||||||
|
|
||||||
class PromoCodeResponse(BaseModel):
|
|
||||||
promocode: str
|
|
||||||
perc: float
|
|
||||||
description: Optional[str] = None
|
|
||||||
Loading…
x
Reference in New Issue
Block a user