parcoursmob/core/application/wallets.go

147 lines
4.2 KiB
Go

package application
import (
"context"
"time"
"git.coopgo.io/coopgo-platform/mobility-accounts/grpcapi"
mobilityaccountsstorage "git.coopgo.io/coopgo-platform/mobility-accounts/storage"
"github.com/rs/zerolog/log"
)
func (h *ApplicationHandler) CreditWallet(ctx context.Context, userid string, amount float64, paymentMethod string, description string) error {
account, err := h.services.GetAccount(userid)
if err != nil {
log.Error().Err(err).Msg("could not retrieve account")
return err
}
// Initialize wallet if it doesn't exist
if account.Data["wallet"] == nil {
account.Data["wallet"] = float64(0)
}
// Initialize wallet history if it doesn't exist
if account.Data["wallet_history"] == nil {
account.Data["wallet_history"] = []map[string]interface{}{}
}
// Determine operation type based on amount sign
operationType := "credit"
if amount < 0 {
operationType = "debit"
}
// Create wallet operation record
operation := map[string]interface{}{
"timestamp": time.Now().Format(time.RFC3339),
"amount": amount,
"payment_method": paymentMethod,
"description": description,
"operation_type": operationType,
}
// Add operation to history
var history []map[string]interface{}
if existingHistory, ok := account.Data["wallet_history"].([]interface{}); ok {
// Convert []interface{} to []map[string]interface{}
for _, item := range existingHistory {
if historyItem, ok := item.(map[string]interface{}); ok {
history = append(history, historyItem)
}
}
} else if existingHistory, ok := account.Data["wallet_history"].([]map[string]interface{}); ok {
history = existingHistory
}
history = append(history, operation)
account.Data["wallet_history"] = history
log.Debug().
Str("userid", userid).
Float64("amount", amount).
Str("paymentMethod", paymentMethod).
Str("description", description).
Int("historyCount", len(history)).
Msg("Adding operation to wallet history")
// Note: wallet balance is NOT updated here - it remains as initial amount
// Balance is calculated from initial amount + sum of all operations
accountproto, err := grpcapi.AccountFromStorageType(&account)
if err != nil {
log.Error().Err(err).Msg("account type transformation issue")
return err
}
_, err = h.services.GRPC.MobilityAccounts.UpdateData(ctx, &grpcapi.UpdateDataRequest{
Account: accountproto,
})
if err != nil {
log.Error().Err(err).Msg("account update issue")
return err
}
log.Info().
Str("userid", userid).
Float64("amount", amount).
Str("payment_method", paymentMethod).
Str("description", description).
Msg("Wallet credited successfully")
return nil
}
// calculateWalletBalance calculates the current wallet balance from initial amount + all operations
func (h *ApplicationHandler) calculateWalletBalance(account mobilityaccountsstorage.Account) float64 {
// Return 0 if account data is nil
if account.Data == nil {
log.Debug().Msg("calculateWalletBalance: account.Data is nil, returning 0")
return float64(0)
}
// Get initial wallet amount (default to 0 if not set)
initialAmount := float64(0)
if walletValue, exists := account.Data["wallet"]; exists && walletValue != nil {
if val, ok := walletValue.(float64); ok {
initialAmount = val
}
}
// Calculate total from all operations
operationsTotal := float64(0)
operationCount := 0
if historyValue, exists := account.Data["wallet_history"]; exists && historyValue != nil {
var operations []map[string]interface{}
// Handle both []interface{} and []map[string]interface{} types
if history, ok := historyValue.([]interface{}); ok {
for _, item := range history {
if operation, ok := item.(map[string]interface{}); ok {
operations = append(operations, operation)
}
}
} else if history, ok := historyValue.([]map[string]interface{}); ok {
operations = history
}
for _, operation := range operations {
if amount, ok := operation["amount"].(float64); ok {
operationsTotal += amount
operationCount++
}
}
}
result := initialAmount + operationsTotal
log.Debug().
Str("accountId", account.ID).
Float64("initialAmount", initialAmount).
Float64("operationsTotal", operationsTotal).
Int("operationCount", operationCount).
Float64("result", result).
Msg("calculateWalletBalance")
return result
}