diff --git a/integration_api.py b/integration_api.py index 110ba4b..fd54734 100644 --- a/integration_api.py +++ b/integration_api.py @@ -189,7 +189,7 @@ async def withdraw_funds( @app.post("/sale", tags=["integration"], response_model=SaleCreateResponse) async def create_sale( req: SaleCreateRequest, - company: Company = Depends(get_current_company_from_jwt), # Используем новую зависимость + company: Company = Depends(get_current_company_from_jwt), db: Session = Depends(get_integration_db) ): """ @@ -198,24 +198,33 @@ async def create_sale( # Устанавливаем уровень изоляции для текущей транзакции db.connection(execution_options={'isolation_level': 'SERIALIZABLE'}) - # 1. Найти Ref по `ref` и `company.id` - # Сначала находим TgAgent, связанный с компанией, затем Ref + # Проверка входных данных + if not req.ref and not req.promocode: + raise HTTPException(status_code=400, detail="Необходимо передать либо ref, либо promocode") - - - tg_agent = db.exec( - select(TgAgent) - .join(Ref) - .where(TgAgent.company_id == company.id) - .where(Ref.ref == req.ref) - ).first() + # 1. Найти Ref по ref и/или promocode + referral = None + if req.ref and req.promocode: + referral_by_ref = db.exec(select(Ref).where(Ref.ref == req.ref)).first() + referral_by_code = db.exec(select(Ref).where(Ref.promocode == req.promocode)).first() + if not referral_by_ref or not referral_by_code: + raise HTTPException(status_code=404, detail="Реферальная ссылка или промокод не найдены") + if referral_by_ref.id != referral_by_code.id: + raise HTTPException(status_code=400, detail="ref и promocode не соответствуют одной ссылке") + referral = referral_by_ref + elif req.ref: + referral = db.exec(select(Ref).where(Ref.ref == req.ref)).first() + if not referral: + raise HTTPException(status_code=404, detail="Реферальная ссылка не найдена") + elif req.promocode: + referral = db.exec(select(Ref).where(Ref.promocode == req.promocode)).first() + if not referral: + raise HTTPException(status_code=404, detail="Промокод не найден") + # Проверяем, что реф действительно принадлежит компании + tg_agent = db.exec(select(TgAgent).where(TgAgent.id == referral.tg_agent_id, TgAgent.company_id == company.id)).first() if not tg_agent: - raise HTTPException(status_code=404, detail="Реферальная ссылка не найдена или не принадлежит данной компании") - - referral = db.exec(select(Ref).where(Ref.ref == req.ref).where(Ref.tg_agent_id == tg_agent.id)).first() - if not referral: - raise HTTPException(status_code=404, detail="Реферальная ссылка не найдена") + raise HTTPException(status_code=404, detail="Реферальная ссылка не принадлежит данной компании") # 2. Проверить, что sale_id уникален для данной компании existing_sale = db.exec( @@ -223,7 +232,6 @@ async def create_sale( .where(Sale.company_id == company.id) .where(Sale.sale_id == req.sale_id) ).first() - if existing_sale: raise HTTPException(status_code=400, detail="Продажа с таким sale_id уже существует для данной компании") @@ -231,12 +239,9 @@ async def create_sale( crediting_amount = req.cost * (company.agent_commission / 100.0) # 4. Проверить и обновить AgentBalance и CompanyBalance - # AgentBalance agent_balance = db.exec(select(AgentBalance).where(AgentBalance.tg_agent_id == tg_agent.id)).first() if not agent_balance: raise HTTPException(status_code=404, detail="Баланс агента не найден") - - # CompanyBalance company_balance = db.exec(select(CompanyBalance).where(CompanyBalance.company_id == company.id)).first() if not company_balance: raise HTTPException(status_code=404, detail="Баланс компании не найден") @@ -251,9 +256,8 @@ async def create_sale( sale_dttm=datetime.utcnow() ) db.add(new_sale) - # Создать AgentTransaction - agent_transaction_status = TransactionStatus.DONE # auto_approve_transactions отвечает только за апрув агентских транзакций на вывод + agent_transaction_status = TransactionStatus.DONE agent_transaction = AgentTransaction( tg_agent_id=tg_agent.id, amount=crediting_amount, @@ -261,7 +265,6 @@ async def create_sale( transaction_group=uuid.uuid4() ) db.add(agent_transaction) - # Обновление балансов для продаж - всегда в замороженный/ожидающий баланс agent_balance.frozen_balance += crediting_amount company_balance.pending_balance -= crediting_amount diff --git a/integration_models.py b/integration_models.py index 13100c8..401d56c 100644 --- a/integration_models.py +++ b/integration_models.py @@ -16,7 +16,8 @@ class IntegrationTokenResponse(BaseModel): # Models for /sale endpoint class SaleCreateRequest(BaseModel): - ref: str + ref: Optional[str] = None + promocode: Optional[str] = None sale_id: str cost: float