package application import ( "context" "net/http" "strconv" "time" "git.coopgo.io/coopgo-platform/mobility-accounts/grpcapi" mobilityaccountsstorage "git.coopgo.io/coopgo-platform/mobility-accounts/storage" "github.com/gorilla/mux" "github.com/rs/zerolog/log" ) func (h ApplicationHandler) CreditWallet(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) userid := vars["userid"] if r.Method != "POST" { w.WriteHeader(http.StatusMethodNotAllowed) return } r.ParseForm() amountStr := r.FormValue("amount") paymentMethod := r.FormValue("payment_method") description := r.FormValue("description") amount, err := strconv.ParseFloat(amountStr, 64) if err != nil { log.Error().Err(err).Msg("could not read amount") w.WriteHeader(http.StatusBadRequest) return } if paymentMethod == "" { paymentMethod = "Paiement en espèce (MMS)" } if err := h.creditWallet(userid, amount, paymentMethod, description); err != nil { log.Error().Err(err).Msg("could not credit wallet") w.WriteHeader(http.StatusInternalServerError) return } http.Redirect(w, r, r.Referer(), http.StatusFound) } func (h *ApplicationHandler) creditWallet(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(context.Background(), &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 }