bookmyservice-ums / app /services /wallet_service.py
MukeshKapoor25's picture
refactor(user): rename user_id to customer_id across all modules
a9ccd3b
from typing import Dict, Any, Optional
import logging
from datetime import datetime
from app.models.wallet_model import WalletModel
from app.schemas.wallet_schema import (
WalletBalanceResponse, WalletSummaryResponse, TransactionHistoryResponse,
TransactionEntry, WalletTransactionResponse
)
logger = logging.getLogger(__name__)
class WalletService:
"""Service for wallet operations"""
@staticmethod
async def get_wallet_balance(customer_id: str) -> WalletBalanceResponse:
"""Get formatted wallet balance for user"""
try:
balance = await WalletModel.get_wallet_balance(customer_id)
return WalletBalanceResponse(
balance=balance,
currency="INR",
formatted_balance=f"₹{balance:,.2f}"
)
except Exception as e:
logger.error(f"Error getting wallet balance for user {customer_id}: {str(e)}")
return WalletBalanceResponse(
balance=0.0,
currency="INR",
formatted_balance="₹0.00"
)
@staticmethod
async def get_wallet_summary(customer_id: str) -> WalletSummaryResponse:
"""Get wallet summary with balance and recent transactions"""
try:
summary_data = await WalletModel.get_wallet_summary(customer_id)
# Convert transactions to schema format
recent_transactions = []
for transaction in summary_data.get("recent_transactions", []):
recent_transactions.append(TransactionEntry(
transaction_id=transaction["_id"],
amount=transaction["amount"],
transaction_type=transaction["transaction_type"],
description=transaction["description"],
reference_id=transaction.get("reference_id"),
balance_before=transaction["balance_before"],
balance_after=transaction["balance_after"],
timestamp=transaction["timestamp"],
status=transaction["status"]
))
balance = summary_data.get("balance", 0.0)
return WalletSummaryResponse(
balance=balance,
formatted_balance=f"₹{balance:,.2f}",
recent_transactions=recent_transactions
)
except Exception as e:
logger.error(f"Error getting wallet summary for user {customer_id}: {str(e)}")
return WalletSummaryResponse(
balance=0.0,
formatted_balance="₹0.00",
recent_transactions=[]
)
@staticmethod
async def get_transaction_history(customer_id: str, page: int = 1, per_page: int = 20) -> TransactionHistoryResponse:
"""Get paginated transaction history"""
try:
history_data = await WalletModel.get_transaction_history(customer_id, page, per_page)
# Convert transactions to schema format
transactions = []
for transaction in history_data.get("transactions", []):
transactions.append(TransactionEntry(
transaction_id=transaction["_id"],
amount=transaction["amount"],
transaction_type=transaction["transaction_type"],
description=transaction["description"],
reference_id=transaction.get("reference_id"),
balance_before=transaction["balance_before"],
balance_after=transaction["balance_after"],
timestamp=transaction["timestamp"],
status=transaction["status"]
))
return TransactionHistoryResponse(
transactions=transactions,
total_count=history_data.get("total_count", 0),
page=page,
per_page=per_page,
total_pages=history_data.get("total_pages", 0)
)
except Exception as e:
logger.error(f"Error getting transaction history for user {customer_id}: {str(e)}")
return TransactionHistoryResponse(
transactions=[],
total_count=0,
page=page,
per_page=per_page,
total_pages=0
)
@staticmethod
async def add_money(customer_id: str, amount: float, payment_method: str,
description: str = "Wallet top-up", reference_id: str = None) -> WalletTransactionResponse:
"""Add money to wallet"""
try:
success = await WalletModel.update_balance(
customer_id=customer_id,
amount=amount,
transaction_type="credit",
description=f"{description} via {payment_method}",
reference_id=reference_id
)
if success:
new_balance = await WalletModel.get_wallet_balance(customer_id)
return WalletTransactionResponse(
success=True,
message=f"Successfully added ₹{amount:,.2f} to wallet",
transaction_id=reference_id,
new_balance=new_balance
)
else:
return WalletTransactionResponse(
success=False,
message="Failed to add money to wallet"
)
except Exception as e:
logger.error(f"Error adding money to wallet for user {customer_id}: {str(e)}")
return WalletTransactionResponse(
success=False,
message="Internal error occurred while adding money"
)
@staticmethod
async def deduct_money(customer_id: str, amount: float, description: str,
reference_id: str = None) -> WalletTransactionResponse:
"""Deduct money from wallet (for payments)"""
try:
success = await WalletModel.update_balance(
customer_id=customer_id,
amount=amount,
transaction_type="debit",
description=description,
reference_id=reference_id
)
if success:
new_balance = await WalletModel.get_wallet_balance(customer_id)
return WalletTransactionResponse(
success=True,
message=f"Successfully deducted ₹{amount:,.2f} from wallet",
transaction_id=reference_id,
new_balance=new_balance
)
else:
return WalletTransactionResponse(
success=False,
message="Insufficient balance or transaction failed"
)
except Exception as e:
logger.error(f"Error deducting money from wallet for user {customer_id}: {str(e)}")
return WalletTransactionResponse(
success=False,
message="Internal error occurred while processing payment"
)
@staticmethod
async def process_refund(customer_id: str, amount: float, description: str,
reference_id: str = None) -> WalletTransactionResponse:
"""Process refund to wallet"""
try:
success = await WalletModel.update_balance(
customer_id=customer_id,
amount=amount,
transaction_type="refund",
description=description,
reference_id=reference_id
)
if success:
new_balance = await WalletModel.get_wallet_balance(customer_id)
return WalletTransactionResponse(
success=True,
message=f"Refund of ₹{amount:,.2f} processed successfully",
transaction_id=reference_id,
new_balance=new_balance
)
else:
return WalletTransactionResponse(
success=False,
message="Failed to process refund"
)
except Exception as e:
logger.error(f"Error processing refund for user {customer_id}: {str(e)}")
return WalletTransactionResponse(
success=False,
message="Internal error occurred while processing refund"
)