144 lines
5.0 KiB
Python
144 lines
5.0 KiB
Python
import logging
|
|
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app import crud, schemas
|
|
from app.models.transaction import TransactionType
|
|
from app.models.wallet import WalletType
|
|
from app.core.email import send_bot_completion_notification
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def process_completed_bot_purchases(db: Session) -> int:
|
|
"""
|
|
Process bot purchases that have reached their end time.
|
|
Returns the number of bot purchases processed.
|
|
"""
|
|
# Get bot purchases that are running but have passed their end time
|
|
completed_due = crud.bot_purchase.get_completed_due(db)
|
|
if not completed_due:
|
|
return 0
|
|
|
|
count = 0
|
|
for purchase in completed_due:
|
|
try:
|
|
# Get user and bot information
|
|
user = crud.user.get(db, id=purchase.user_id)
|
|
bot = crud.bot.get(db, id=purchase.bot_id)
|
|
|
|
if not user or not bot:
|
|
logger.error(
|
|
f"User or bot not found for bot purchase {purchase.id}. "
|
|
f"User ID: {purchase.user_id}, Bot ID: {purchase.bot_id}"
|
|
)
|
|
continue
|
|
|
|
# Get user's trading wallet
|
|
trading_wallet = crud.wallet.get_by_user_and_type(
|
|
db, user_id=user.id, wallet_type=WalletType.TRADING
|
|
)
|
|
if not trading_wallet:
|
|
logger.error(
|
|
f"Trading wallet not found for user {user.id} "
|
|
f"when processing bot purchase {purchase.id}"
|
|
)
|
|
continue
|
|
|
|
# Calculate the total amount to be credited (principal + ROI)
|
|
principal = purchase.amount
|
|
roi = purchase.expected_roi_amount
|
|
total = principal + roi
|
|
|
|
# Update trading wallet balance
|
|
crud.wallet.update_balance(db, wallet_id=trading_wallet.id, amount=total, add=True)
|
|
|
|
# Create transaction records
|
|
# 1. Return of principal
|
|
principal_transaction = crud.transaction.create(
|
|
db,
|
|
obj_in=schemas.TransactionCreate(
|
|
user_id=user.id,
|
|
wallet_id=trading_wallet.id,
|
|
amount=principal,
|
|
transaction_type=TransactionType.BOT_EARNING,
|
|
description=f"Bot {bot.name} - Return of principal",
|
|
bot_purchase_id=purchase.id,
|
|
),
|
|
)
|
|
|
|
# 2. ROI
|
|
roi_transaction = crud.transaction.create(
|
|
db,
|
|
obj_in=schemas.TransactionCreate(
|
|
user_id=user.id,
|
|
wallet_id=trading_wallet.id,
|
|
amount=roi,
|
|
transaction_type=TransactionType.BOT_EARNING,
|
|
description=f"Bot {bot.name} - ROI",
|
|
bot_purchase_id=purchase.id,
|
|
related_transaction_id=principal_transaction.id,
|
|
),
|
|
)
|
|
|
|
# Update the first transaction to reference the second
|
|
crud.transaction.update(
|
|
db,
|
|
db_obj=principal_transaction,
|
|
obj_in={"related_transaction_id": roi_transaction.id},
|
|
)
|
|
|
|
# Mark the bot purchase as completed
|
|
crud.bot_purchase.complete(db, db_obj=purchase)
|
|
|
|
# Send email notification
|
|
send_bot_completion_notification(
|
|
email_to=user.email,
|
|
bot_name=bot.name,
|
|
amount=principal,
|
|
roi=roi,
|
|
)
|
|
|
|
count += 1
|
|
except Exception as e:
|
|
logger.error(
|
|
f"Error processing bot purchase {purchase.id}: {str(e)}"
|
|
)
|
|
|
|
return count
|
|
|
|
|
|
def get_bot_simulation_stats(db: Session) -> dict:
|
|
"""
|
|
Get statistics about bot simulations.
|
|
"""
|
|
# Get counts by status
|
|
running_count = len(crud.bot_purchase.get_by_status(
|
|
db, status=schemas.BotPurchaseStatus.RUNNING
|
|
))
|
|
completed_count = len(crud.bot_purchase.get_by_status(
|
|
db, status=schemas.BotPurchaseStatus.COMPLETED
|
|
))
|
|
cancelled_count = len(crud.bot_purchase.get_by_status(
|
|
db, status=schemas.BotPurchaseStatus.CANCELLED
|
|
))
|
|
|
|
# Calculate total invested amount (running bots)
|
|
running_purchases = crud.bot_purchase.get_by_status(
|
|
db, status=schemas.BotPurchaseStatus.RUNNING
|
|
)
|
|
total_invested = sum(p.amount for p in running_purchases)
|
|
|
|
# Calculate total ROI generated (completed bots)
|
|
completed_purchases = crud.bot_purchase.get_by_status(
|
|
db, status=schemas.BotPurchaseStatus.COMPLETED
|
|
)
|
|
total_roi_generated = sum(p.expected_roi_amount for p in completed_purchases)
|
|
|
|
return {
|
|
"running_count": running_count,
|
|
"completed_count": completed_count,
|
|
"cancelled_count": cancelled_count,
|
|
"total_invested": total_invested,
|
|
"total_roi_generated": total_roi_generated,
|
|
} |