185 lines
5.1 KiB
Go
185 lines
5.1 KiB
Go
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
|
|
}
|