147 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			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
 | 
						|
}
 |