forked from zovos/bot_tg
Исправление точности вещественных чисел при ставках, казино, переводах и вкладах
This commit is contained in:
parent
89a14f2ebf
commit
191aa8ef93
5 changed files with 34 additions and 30 deletions
|
|
@ -286,26 +286,26 @@ async def get_match_by_index(sport_alias: str, index: int) -> dict | None:
|
|||
return None
|
||||
|
||||
|
||||
def place_bet(user_id: int, match: dict, sport: str, chosen_team: str, amount: float) -> str:
|
||||
def place_bet(user_id: int, match: dict, sport: str, chosen_team: str, amount: float) -> tuple[bool, str]:
|
||||
current = get_user_length(user_id)
|
||||
if current is None:
|
||||
return "Сначала заведи счёт через /penis, братуха."
|
||||
return False, "Сначала заведи счёт через /penis, братуха."
|
||||
if current <= 0:
|
||||
return "🚫 С кредитом ставки не принимаем."
|
||||
return False, "🚫 С кредитом ставки не принимаем."
|
||||
if amount <= 0:
|
||||
return "Ставка должна быть больше нуля."
|
||||
return False, "Ставка должна быть больше нуля."
|
||||
if amount > config.BET_MAX_AMOUNT:
|
||||
return f"Максимальная ставка — {config.BET_MAX_AMOUNT} см."
|
||||
if amount > current:
|
||||
return f"У тебя {current:.1f} см, а ставишь {amount:.1f}. Не хватает, фраер."
|
||||
return False, f"Максимальная ставка — {config.BET_MAX_AMOUNT} см."
|
||||
if round(amount, 2) > round(current, 2):
|
||||
return False, f"У тебя {current:.1f} см, а ставишь {amount:.1f}. Не хватает, фраер."
|
||||
|
||||
team_odds = match["odds"].get(chosen_team)
|
||||
if team_odds is None:
|
||||
return f"Исход не найден. Доступные: {describe_match_outcomes(match)}"
|
||||
return False, f"Исход не найден. Доступные: {describe_match_outcomes(match)}"
|
||||
|
||||
new_length = update_user_length(user_id, -amount)
|
||||
if new_length is None:
|
||||
return "Ошибка БД."
|
||||
return False, "Ошибка БД."
|
||||
|
||||
now_ts = int(_time.time())
|
||||
try:
|
||||
|
|
@ -323,12 +323,11 @@ def place_bet(user_id: int, match: dict, sport: str, chosen_team: str, amount: f
|
|||
except psycopg2.Error:
|
||||
logger.exception("Failed to place bet")
|
||||
update_user_length(user_id, amount)
|
||||
return "Ошибка БД."
|
||||
return False, "Ошибка БД."
|
||||
|
||||
potential = round(amount * team_odds, 1)
|
||||
return (
|
||||
return True, (
|
||||
f"✅ Ставка принята!\n"
|
||||
f"🏟 {match['home']} vs {match['away']}\n"
|
||||
f"📌 {chosen_team} (x{team_odds:.2f})\n"
|
||||
f"💰 Ставка: {amount:.1f} см\n"
|
||||
f"🎯 Возможный выигрыш: {potential:.1f} см\n"
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ def play_casino(user_id: int, bet: float) -> str:
|
|||
return f"Максимальная ставка — {config.CASINO_MAX_BET} см, не жадничай."
|
||||
if bet <= 0:
|
||||
return "Ставка должна быть больше нуля, фраер."
|
||||
if bet > current:
|
||||
if round(bet, 2) > round(current, 2):
|
||||
return f"У тебя {current:.1f} см, а ставишь {bet:.1f}. Столько нет, фраер."
|
||||
|
||||
reels, matches = spin_slots()
|
||||
|
|
|
|||
|
|
@ -179,7 +179,8 @@ class EconomyManager:
|
|||
return False
|
||||
|
||||
from_balance = self.get_user_balance(from_user_id)
|
||||
if amount > from_balance * 0.2 or from_balance < amount:
|
||||
limit = round(from_balance * 0.2, 2)
|
||||
if round(amount, 2) > limit or round(from_balance, 2) < round(amount, 2):
|
||||
return False
|
||||
|
||||
with get_conn() as conn:
|
||||
|
|
@ -201,15 +202,17 @@ class EconomyManager:
|
|||
logger.info(f"Transfer: {amount} from user {from_user_id} to user {to_user_id}")
|
||||
return True
|
||||
|
||||
def create_deposit(self, user_id: int, amount: float, days: int) -> bool:
|
||||
def create_deposit(self, user_id: int, amount: float, days: int) -> tuple[bool, str]:
|
||||
if amount <= 0:
|
||||
return False
|
||||
return False, "Сумма вклада должна быть больше нуля."
|
||||
|
||||
balance = self.get_user_balance(user_id)
|
||||
min_deposit = float(self.get_setting('deposit_min_amount'))
|
||||
|
||||
if amount < min_deposit or balance < amount:
|
||||
return False
|
||||
if round(amount, 2) < round(min_deposit, 2):
|
||||
return False, f"Минимальная сумма вклада — {min_deposit:.1f} см. Твой баланс: {balance:.1f} см."
|
||||
if round(balance, 2) < round(amount, 2):
|
||||
return False, f"Недостаточно средств. Твой баланс: {balance:.1f} см, а сумма вклада: {amount:.1f} см."
|
||||
|
||||
central_bank_rate = float(self.get_setting('central_bank_rate'))
|
||||
matures_at = datetime.now() + timedelta(days=days)
|
||||
|
|
@ -230,7 +233,7 @@ class EconomyManager:
|
|||
''', (user_id, amount, central_bank_rate, matures_at))
|
||||
|
||||
logger.info(f"Deposit created: user {user_id}, amount {amount}, rate {central_bank_rate}%")
|
||||
return True
|
||||
return True, "Вклад успешно открыт!"
|
||||
|
||||
def create_loan(self, user_id: int, amount: float, days: int) -> bool:
|
||||
if amount <= 0:
|
||||
|
|
@ -239,7 +242,7 @@ class EconomyManager:
|
|||
max_loan = float(self.get_setting('loan_max_amount'))
|
||||
loan_rate = float(self.get_setting('loan_interest_rate'))
|
||||
|
||||
if amount > max_loan:
|
||||
if round(amount, 2) > round(max_loan, 2):
|
||||
return False
|
||||
|
||||
with get_conn() as conn:
|
||||
|
|
@ -251,13 +254,13 @@ class EconomyManager:
|
|||
(user_id,),
|
||||
)
|
||||
outstanding = float(cur.fetchone()['total'])
|
||||
if outstanding + amount > max_loan:
|
||||
if round(outstanding + amount, 2) > round(max_loan, 2):
|
||||
return False
|
||||
|
||||
# ЦБ должен иметь достаточно капитала
|
||||
cur.execute("SELECT capital FROM central_bank WHERE id=1")
|
||||
cb_capital = float(cur.fetchone()['capital'])
|
||||
if cb_capital < amount:
|
||||
if round(cb_capital, 2) < round(amount, 2):
|
||||
return False
|
||||
|
||||
due_at = datetime.now() + timedelta(days=days)
|
||||
|
|
@ -293,10 +296,10 @@ class EconomyManager:
|
|||
if not loan or loan['is_repaid']:
|
||||
return False
|
||||
|
||||
total_repayment = loan['amount'] * (1 + loan['interest_rate'] / 100)
|
||||
total_repayment = round(loan['amount'] * (1 + loan['interest_rate'] / 100), 2)
|
||||
|
||||
balance = self.get_user_balance(user_id)
|
||||
if balance < total_repayment:
|
||||
if round(balance, 2) < total_repayment:
|
||||
return False
|
||||
|
||||
wcur = conn.cursor()
|
||||
|
|
@ -479,7 +482,7 @@ class EconomyManager:
|
|||
logger.info(f"Central bank updated: {capital_change} ({transaction_type})")
|
||||
|
||||
def emit_money(self, amount: float, reason: str = "") -> bool:
|
||||
if self.get_central_bank_stats()['capital'] < amount:
|
||||
if round(self.get_central_bank_stats()['capital'], 2) < round(amount, 2):
|
||||
return False
|
||||
self.update_central_bank(-amount, 'emission', reason)
|
||||
logger.info(f"Money emitted: {amount} cm ({reason})")
|
||||
|
|
|
|||
6
main.py
6
main.py
|
|
@ -1263,12 +1263,12 @@ async def handle_deposit_cmd(message: Message):
|
|||
await message.reply("Сумма и дни должны быть положительными.", parse_mode=None)
|
||||
return
|
||||
|
||||
success = await asyncio.to_thread(economy.create_deposit, message.from_user.id, amount, days)
|
||||
success, error_msg = await asyncio.to_thread(economy.create_deposit, message.from_user.id, amount, days)
|
||||
if success:
|
||||
rate = economy.get_setting('central_bank_rate')
|
||||
await message.reply(f"✅ Вклад открыт!\n💰 Сумма: {amount:.1f} см\n📅 Срок: {days} дней\n📈 Ставка: {rate}% годовых", parse_mode=None)
|
||||
else:
|
||||
await message.reply("❌ Не удалось открыть вклад. Проверь баланс и минимальную сумму.", parse_mode=None)
|
||||
await message.reply(f"❌ Не удалось открыть вклад. {error_msg}", parse_mode=None)
|
||||
|
||||
async def handle_loans_cmd(message: Message):
|
||||
"""Показать кредиты"""
|
||||
|
|
@ -1562,7 +1562,7 @@ async def handle_bet_cmd(message: Message):
|
|||
)
|
||||
return
|
||||
|
||||
result = await asyncio.to_thread(place_bet, message.from_user.id, match, sport_alias, team, amount)
|
||||
success, result = await asyncio.to_thread(place_bet, message.from_user.id, match, sport_alias, team, amount)
|
||||
await message.reply(result, parse_mode=None)
|
||||
|
||||
async def handle_mybets_cmd(message: Message):
|
||||
|
|
|
|||
|
|
@ -253,7 +253,9 @@ async def create_bet(
|
|||
raise HTTPException(status_code=400, detail="Неверный исход ставки")
|
||||
|
||||
# 3. Разместить ставку (синхронная функция)
|
||||
result = await asyncio.to_thread(place_bet, user_id, match, req.league, team, req.amount)
|
||||
success, result = await asyncio.to_thread(place_bet, user_id, match, req.league, team, req.amount)
|
||||
if not success:
|
||||
raise HTTPException(status_code=400, detail=result)
|
||||
return {"message": result}
|
||||
|
||||
|
||||
|
|
@ -294,7 +296,7 @@ async def play_casino_api(
|
|||
raise HTTPException(status_code=400, detail=f"Макс ставка: {config.CASINO_MAX_BET} см")
|
||||
if req.bet <= 0:
|
||||
raise HTTPException(status_code=400, detail="Ставка > 0")
|
||||
if req.bet > current:
|
||||
if round(req.bet, 2) > round(current, 2):
|
||||
raise HTTPException(status_code=400, detail=f"У тебя {current:.1f} см")
|
||||
|
||||
reels, match_count = await asyncio.to_thread(spin_slots)
|
||||
|
|
|
|||
Loading…
Reference in a new issue