update calculate user balance
This commit is contained in:
parent
f9356c6bbe
commit
dd18e74529
@ -47,8 +47,8 @@ export default class UserHandler {
|
||||
const activeWalletsBalance = await WalletService.getActiveWalletsBalance(userStats.id);
|
||||
const archivedWalletsBalance = await WalletService.getArchivedWalletsBalance(userStats.id);
|
||||
|
||||
// Общий баланс (крипто + бонусы + total_balance)
|
||||
const totalBalance = activeWalletsBalance + archivedWalletsBalance + userStats.bonus_balance + (userStats.total_balance || 0);
|
||||
// Доступный баланс (bonus_balance + total_balance)
|
||||
const availableBalance = userStats.bonus_balance + (userStats.total_balance || 0);
|
||||
|
||||
const locationText = userStats.country && userStats.city && userStats.district
|
||||
? `${userStats.country}, ${userStats.city}, ${userStats.district}`
|
||||
@ -66,7 +66,7 @@ export default class UserHandler {
|
||||
├ Active Wallets: ${userStats.crypto_wallet_count || 0} ($${activeWalletsBalance.toFixed(2)})
|
||||
├ Archived Wallets: ${userStats.archived_wallet_count || 0} ($${archivedWalletsBalance.toFixed(2)})
|
||||
├ Bonus Balance: $${userStats.bonus_balance || 0}
|
||||
└ Available Balance: $${totalBalance.toFixed(2)}
|
||||
└ Available Balance: $${availableBalance.toFixed(2)}
|
||||
|
||||
📅 Member since: ${new Date(userStats.created_at).toLocaleDateString()}
|
||||
`;
|
||||
|
@ -248,26 +248,21 @@ export default class UserPurchaseHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
// Логируем данные для отладки
|
||||
console.log('Purchase data:', purchase);
|
||||
console.log('User data:', user);
|
||||
|
||||
// Обновляем статус покупки в базе данных
|
||||
await PurchaseService.updatePurchaseStatus(purchaseId, 'received');
|
||||
|
||||
// Добавляем транзакцию в таблицу transactions
|
||||
await db.runAsync(`
|
||||
INSERT INTO transactions (user_id, wallet_type, tx_hash, amount, created_at)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
`, [
|
||||
user.id, // ID пользователя
|
||||
purchase.wallet_type || 'unknown', // Тип кошелька (если не указан, то "unknown")
|
||||
purchase.tx_hash || 'no_hash', // Хеш транзакции (если не указан, то "no_hash")
|
||||
purchase.total_price, // Сумма транзакции
|
||||
new Date().toISOString() // Дата создания транзакции
|
||||
]);
|
||||
|
||||
console.log('Transaction added successfully'); // Логируем успешную вставку
|
||||
// Добавляем запись в таблицу transactions
|
||||
await db.runAsync(
|
||||
`INSERT INTO transactions (user_id, wallet_type, tx_hash, amount, created_at)
|
||||
VALUES (?, ?, ?, ?, ?)`,
|
||||
[
|
||||
user.id, // ID пользователя
|
||||
purchase.wallet_type, // Источник списания (например, "bonus_50, crypto_30")
|
||||
purchase.tx_hash || 'no_hash', // Хеш транзакции (если не указан, то "no_hash")
|
||||
purchase.total_price, // Сумма транзакции
|
||||
new Date().toISOString() // Дата создания транзакции
|
||||
]
|
||||
);
|
||||
|
||||
// Отправляем уведомление администраторам
|
||||
const adminIds = config.ADMIN_IDS; // Используем массив ADMIN_IDS
|
||||
|
@ -69,13 +69,9 @@ export default class UserWalletsHandler {
|
||||
// Бонусный баланс
|
||||
message += `🎁 *Bonus Balance:* $${updatedUser.bonus_balance.toFixed(2)}\n`;
|
||||
|
||||
// Общий баланс (крипто + бонусы + total_balance)
|
||||
const totalBalance = totalUsdValue + updatedUser.bonus_balance + (updatedUser.total_balance || 0);
|
||||
message += `💰 *Total Balance:* $${totalBalance.toFixed(2)}\n`;
|
||||
|
||||
// Доступный баланс (общий баланс минус расходы на покупки)
|
||||
const availableBalance = totalBalance; // Теперь availableBalance включает криптобаланс
|
||||
message += `💳 *Available Balance:* $${availableBalance.toFixed(2)}\n`;
|
||||
// Доступный баланс (bonus_balance + total_balance)
|
||||
const availableBalance = updatedUser.bonus_balance + (updatedUser.total_balance || 0);
|
||||
message += `💰 *Available Balance:* $${availableBalance.toFixed(2)}\n`;
|
||||
} else {
|
||||
message = 'You don\'t have any active wallets yet.';
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
import db from "../config/database.js";
|
||||
import CryptoJS from "crypto-js"; // Импортируем библиотеку crypto-js
|
||||
import UserService from "../services/userService.js";
|
||||
|
||||
class PurchaseService {
|
||||
static async getPurchasesByUserId(userId, limit, offset) {
|
||||
try {
|
||||
@ -42,16 +44,62 @@ class PurchaseService {
|
||||
|
||||
static async createPurchase(userId, productId, walletType, quantity, totalPrice) {
|
||||
try {
|
||||
const user = await UserService.getUserByUserId(userId);
|
||||
if (!user) {
|
||||
throw new Error('User not found');
|
||||
}
|
||||
|
||||
// Обновляем крипто-баланс пользователя перед началом покупки
|
||||
await UserService.recalculateUserBalanceByTelegramId(user.telegram_id);
|
||||
|
||||
let remainingAmount = totalPrice;
|
||||
let usedBonus = 0;
|
||||
let usedCrypto = 0;
|
||||
let sourceWalletType = '';
|
||||
|
||||
// Сначала списываем с бонусного баланса
|
||||
if (user.bonus_balance > 0) {
|
||||
usedBonus = Math.min(user.bonus_balance, remainingAmount);
|
||||
remainingAmount -= usedBonus;
|
||||
|
||||
// Обновляем бонусный баланс пользователя
|
||||
await db.runAsync(
|
||||
'UPDATE users SET bonus_balance = bonus_balance - ? WHERE id = ?',
|
||||
[usedBonus, userId]
|
||||
);
|
||||
|
||||
// Добавляем информацию о списании с бонусного баланса
|
||||
sourceWalletType += `bonus_${usedBonus}`;
|
||||
}
|
||||
|
||||
// Если осталась сумма, списываем с крипто-баланса
|
||||
if (remainingAmount > 0) {
|
||||
usedCrypto = remainingAmount;
|
||||
|
||||
// Обновляем крипто-баланс пользователя
|
||||
await db.runAsync(
|
||||
'UPDATE users SET total_balance = total_balance - ? WHERE id = ?',
|
||||
[usedCrypto, userId]
|
||||
);
|
||||
|
||||
// Добавляем информацию о списании с крипто-баланса
|
||||
if (sourceWalletType) {
|
||||
sourceWalletType += `, crypto_${usedCrypto}`;
|
||||
} else {
|
||||
sourceWalletType = `crypto_${usedCrypto}`;
|
||||
}
|
||||
}
|
||||
|
||||
// Генерируем MD5-хеш для tx_hash
|
||||
const txHash = CryptoJS.MD5(Date.now().toString()).toString();
|
||||
|
||||
// Вставка новой покупки в базу данных
|
||||
|
||||
// Вставляем новую покупку в базу данных
|
||||
const result = await db.runAsync(
|
||||
`INSERT INTO purchases (user_id, product_id, wallet_type, quantity, total_price, purchase_date, tx_hash)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
||||
[userId, productId, walletType, quantity, totalPrice, new Date().toISOString(), txHash]
|
||||
[userId, productId, sourceWalletType, quantity, totalPrice, new Date().toISOString(), txHash]
|
||||
);
|
||||
|
||||
|
||||
// Возвращаем ID новой покупки
|
||||
return result.lastID;
|
||||
} catch (error) {
|
||||
@ -62,6 +110,29 @@ class PurchaseService {
|
||||
|
||||
static async updatePurchaseStatus(purchaseId, status) {
|
||||
try {
|
||||
const purchase = await this.getPurchaseById(purchaseId);
|
||||
if (!purchase) {
|
||||
throw new Error('Purchase not found');
|
||||
}
|
||||
|
||||
if (status === 'canceled') {
|
||||
const user = await UserService.getUserByUserId(purchase.user_id);
|
||||
|
||||
// Возвращаем средства на бонусный или крипто-баланс
|
||||
if (purchase.wallet_type === 'bonus') {
|
||||
await db.runAsync(
|
||||
'UPDATE users SET bonus_balance = bonus_balance + ? WHERE id = ?',
|
||||
[purchase.total_price, user.id]
|
||||
);
|
||||
} else {
|
||||
await db.runAsync(
|
||||
'UPDATE users SET total_balance = total_balance + ? WHERE id = ?',
|
||||
[purchase.total_price, user.id]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Обновляем статус покупки
|
||||
await db.runAsync(
|
||||
'UPDATE purchases SET status = ? WHERE id = ?',
|
||||
[status, purchaseId]
|
||||
|
@ -1,5 +1,9 @@
|
||||
// userService.js
|
||||
|
||||
import db from "../config/database.js";
|
||||
import Wallet from "../models/Wallet.js";
|
||||
import WalletUtils from "../utils/walletUtils.js";
|
||||
|
||||
|
||||
class UserService {
|
||||
// Функция для нормализации telegram_id
|
||||
@ -119,22 +123,50 @@ class UserService {
|
||||
static async recalculateUserBalanceByTelegramId(telegramId) {
|
||||
const normalizedTelegramId = this.normalizeTelegramId(telegramId);
|
||||
const user = await this.getUserByTelegramId(normalizedTelegramId);
|
||||
|
||||
|
||||
if (!user) {
|
||||
return;
|
||||
}
|
||||
|
||||
const archivedBalance = await Wallet.getArchivedWalletsBalance(user.id);
|
||||
const activeBalance = await Wallet.getActiveWalletsBalance(user.id);
|
||||
|
||||
const purchases = await db.getAsync(
|
||||
`SELECT SUM(total_price) as total_sum FROM purchases WHERE user_id = ?`,
|
||||
[user.id]
|
||||
);
|
||||
|
||||
const userTotalBalance = (activeBalance + archivedBalance) - (purchases?.total_sum || 0);
|
||||
|
||||
await db.runAsync(`UPDATE users SET total_balance = ? WHERE id = ?`, [userTotalBalance, user.id]);
|
||||
|
||||
try {
|
||||
// Получаем все крипто-балансы пользователя
|
||||
const cryptoBalances = await db.allAsync(
|
||||
`SELECT wallet_type, balance FROM crypto_wallets WHERE user_id = ?`,
|
||||
[user.id]
|
||||
);
|
||||
|
||||
// Получаем актуальные курсы криптовалют
|
||||
const prices = await WalletUtils.getCryptoPrices();
|
||||
|
||||
// Пересчитываем балансы в доллары
|
||||
let totalCryptoBalance = 0;
|
||||
for (const wallet of cryptoBalances) {
|
||||
const baseType = WalletUtils.getBaseWalletType(wallet.wallet_type); // Убираем суффиксы
|
||||
const rate = prices[baseType.toLowerCase()] || 0; // Получаем курс для базового типа
|
||||
totalCryptoBalance += wallet.balance * rate;
|
||||
}
|
||||
|
||||
// Получаем сумму всех покупок в крипте
|
||||
const cryptoPurchases = await db.getAsync(
|
||||
`SELECT SUM(total_price) as total_sum FROM purchases
|
||||
WHERE user_id = ? AND wallet_type LIKE 'crypto%'`,
|
||||
[user.id]
|
||||
);
|
||||
|
||||
// Вычитаем сумму покупок из общего крипто-баланса
|
||||
const remainingBalance = totalCryptoBalance - (cryptoPurchases?.total_sum || 0);
|
||||
|
||||
// Обновляем поле total_balance в таблице users
|
||||
await db.runAsync(
|
||||
`UPDATE users SET total_balance = ? WHERE id = ?`,
|
||||
[remainingBalance, user.id]
|
||||
);
|
||||
|
||||
console.log(`[DEBUG] Updated total_balance for user ${user.id}: ${remainingBalance}`);
|
||||
} catch (error) {
|
||||
console.error('Error recalculating user balance:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
static async updateUserLocation(telegramId, country, city, district) {
|
||||
@ -164,28 +196,13 @@ class UserService {
|
||||
|
||||
static async getUserBalance(userId) {
|
||||
try {
|
||||
// Пересчитываем баланс перед получением
|
||||
const user = await this.getUserByUserId(userId);
|
||||
if (!user) {
|
||||
throw new Error('User not found');
|
||||
}
|
||||
|
||||
await this.recalculateUserBalanceByTelegramId(user.telegram_id);
|
||||
|
||||
// Получаем обновленный баланс
|
||||
const updatedUser = await db.getAsync(
|
||||
`SELECT total_balance, bonus_balance
|
||||
FROM users
|
||||
WHERE id = ?`,
|
||||
[userId]
|
||||
);
|
||||
|
||||
if (!updatedUser) {
|
||||
throw new Error('User not found');
|
||||
}
|
||||
|
||||
// Возвращаем сумму основного и бонусного баланса
|
||||
return updatedUser.total_balance + updatedUser.bonus_balance;
|
||||
// Возвращаем сумму доступного крипто-баланса и бонусного баланса
|
||||
return user.total_balance + user.bonus_balance;
|
||||
} catch (error) {
|
||||
console.error('Error getting user balance:', error);
|
||||
throw error;
|
||||
|
Loading…
Reference in New Issue
Block a user