FOX - Currency Switcher for WooCommerce

Comment corriger les rapports d'analyse WooCommerce pour les boutiques multi-devises

Si vous gérez une boutique WooCommerce multi-devises avec WOOCS et que vos rapports WooCommerce Analytics affichent des totaux incorrects, ce guide vous aidera à résoudre le problème.

Le problème

Symptôme : WooCommerce Analytics affiche des chiffres de vente erronés lorsque vous avez des commandes dans plusieurs devises. Exemple :
  • Commande #1 : 100 USD
  • Commande #2 : 100 EUR
  • Commande #3 : 100 GBP
Ce que WooCommerce Analytics affiche :
Total Sales: $300
C'est FAUX ! WooCommerce additionne des devises différentes sans les convertir : 100 USD + 100 EUR + 100 GBP ≠ 300 USD Le calcul correct devrait être :
$100 USD + €100 EUR ($109) + £100 GBP ($127) = $336 USD

Pourquoi cela se produit

WooCommerce Analytics ne prend pas en charge nativement les multi-devises. Il additionne simplement tous les totaux des commandes sans vérifier la devise, traitant tous les nombres comme s'ils étaient dans votre devise de base. Rapports concernés :
  • Rapports de revenus
  • Ventes par date
  • Analyses des ventes de produits
  • Rapports de taxes
  • Rapports d'expédition
Cela affecte :
  • Décisions commerciales basées sur des données erronées
  • Calculs fiscaux
  • Rapports financiers
  • Analyse du ROI

La solution

Ce code convertit toutes les commandes dans votre devise de base lors de l'affichage des rapports WooCommerce Analytics, vous donnant des totaux précis.

Étape 1 : Ajouter le code à votre site

Ajoutez ce code au functions.php de votre thème enfant ou utilisez le plugin Code Snippets. Code complet :
/**
 * Fix WooCommerce Analytics for multi-currency stores (WOOCS)
 * Converts all orders to base currency for accurate reporting
 */
// Clear WooCommerce reports cache (run once, then remove this)
add_action('init', function () {
    if (current_user_can('manage_woocommerce')) {
        global $wpdb;
        $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '%_wc_report_%'");
        $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '%wc_admin_report_%'");
    }
});

// Disable Analytics cache to force real-time conversion
add_filter('woocommerce_analytics_enable_cache', '__return_false');

// Convert order totals to base currency in Analytics queries
add_filter('woocommerce_analytics_orders_select_query', function ($results, $args) {
    if (!$results || !isset($results->data) || empty($results->data)) {
        return $results;
    }

    $base_currency = get_woocommerce_currency();

    foreach ($results->data as $key => $order_data) {
        $order_id = $order_data['order_id'];
        $order_currency = get_post_meta($order_id, '_order_currency', true);

        // Only convert if order currency differs from base currency
        if ($order_currency AND $order_currency !== $base_currency) {
            // Get exchange rate from order meta (rate at time of purchase)
            $exchange_rate = get_post_meta($order_id, '_woocs_order_rate', true);

            // Fallback to current rate if historical rate not found
            if (!$exchange_rate) {
                $exchange_rate = woocs_get_exchange_rate($order_currency, $base_currency);
            }

            // Convert all monetary values
            if (isset($order_data['net_total'])) {
                $results->data[$key]['net_total'] = floatval($order_data['net_total']) * floatval($exchange_rate);
            }

            if (isset($order_data['total_sales'])) {
                $results->data[$key]['total_sales'] = floatval($order_data['total_sales']) * floatval($exchange_rate);
            }

            if (isset($order_data['tax_total'])) {
                $results->data[$key]['tax_total'] = floatval($order_data['tax_total']) * floatval($exchange_rate);
            }

            if (isset($order_data['shipping_total'])) {
                $results->data[$key]['shipping_total'] = floatval($order_data['shipping_total']) * floatval($exchange_rate);
            }
        }
    }

    return $results;
}, 10, 2);

/**
 * Helper function to get exchange rate between currencies
 */
function woocs_get_exchange_rate($from_currency, $to_currency) {
    global $WOOCS;

    if (!isset($WOOCS) || !$WOOCS) {
        return 1;
    }

    $currencies = $WOOCS->get_currencies();

    if (isset($currencies[$from_currency]) AND isset($currencies[$to_currency])) {
        $from_rate = floatval($currencies[$from_currency]['rate']);
        $to_rate = floatval($currencies[$to_currency]['rate']);

        if ($from_rate > 0) {
            return $to_rate / $from_rate;
        }
    }

    return 1;
}
 

Étape 2 : Vérifier les résultats

  1. Allez dans WooCommerce → Analytics → Revenus
  2. Vérifiez vos totaux de ventes
  3. Comparez avec les données précédentes (incorrectes)
  4. Les totaux doivent maintenant être précis, convertis dans la devise de base

Comment cela fonctionne

Partie 1 : Vidage du cache

add_action('init', function () {
    global $wpdb;
    $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '%_wc_report_%'");
    ...
});
Ce qu'il fait : Supprime les anciens rapports en cache qui contiennent des données incorrectes Ce code ne s'exécute que pour les utilisateurs administrateurs

Partie 2 : Désactiver le cache Analytics

add_filter('woocommerce_analytics_enable_cache', '__return_false');
Ce qu'il fait : Force WooCommerce Analytics à recalculer les données à chaque vue au lieu d'utiliser les valeurs en cache Compromis : Les rapports peuvent se charger un peu plus lentement, mais les données seront toujours précises

Partie 3 : Convertir les totaux des commandes

add_filter('woocommerce_analytics_orders_select_query', function ($results, $args) {
    // Convert each order to base currency
    ...
});
Ce qu'il fait :
  • Intercepte les requêtes de base de données Analytics
  • Vérifie la devise de chaque commande
  • Si différente de la devise de base, convertit en utilisant le taux de change
  • Renvoie les valeurs converties à Analytics

Partie 4 : Fonction de taux de change

function woocs_get_exchange_rate($from_currency, $to_currency) {
    // Calculate conversion rate between currencies
    ...
}
Ce qu'il fait :
  • Obtient les taux de change actuels depuis WOOCS
  • Calcule le taux de conversion entre deux devises
  • Utilisé comme solution de repli si le taux historique n'est pas trouvé

Remarques importantes

Taux de change historiques vs actuels

Le code utilise les taux historiques lorsque possible :
$exchange_rate = get_post_meta($order_id, '_woocs_order_rate', true);
Pourquoi c'est important :
  • Commande d'il y a 6 mois : Utilisation du taux de change de cette date
  • Rapports financiers plus précis
  • Reflète le revenu réel au moment de la vente
Solution de repli : Si le taux historique n'est pas disponible, utilise le taux actuel de WOOCS.

Impact sur les performances

Ce qui change :
  • ✅ Rapports multi-devises précis
  • ❌ Les rapports peuvent se charger 0,5 à 2 secondes plus lentement (pas de cache)
  • ❌ Augmentation des requêtes de base de données
Recommandation :
  • Petites boutiques (< 1 000 commandes/mois) : Impact négligeable
  • Boutiques moyennes (1 000-10 000 commandes/mois) : Ralentissement mineur acceptable pour la précision
  • Grandes boutiques (10 000+ commandes/mois) : Surveiller les performances, envisager une optimisation

Cache désactivé

add_filter('woocommerce_analytics_enable_cache', '__return_false');
Cela est nécessaire car les rapports en cache afficheraient des devises mélangées. La conversion se fait en temps réel à chaque vue de rapport. Approche alternative pour les grandes boutiques :
  • Supprimer la ligne de désactivation du cache
  • Vider le cache manuellement lorsque les taux de change changent significativement
  • Accepter une légère imprécision pour de meilleures performances

Dépannage

Les rapports affichent toujours des totaux incorrects

Problème : Les chiffres n'ont pas changé après l'ajout du code Solutions :
  1. Cache non vidé
    • Assurez-vous que le code de vidage du cache s'est exécuté
    • Visitez le panneau d'administration en étant connecté en tant qu'administrateur
    • Vérifiez si vous avez la capacité manage_woocommerce
  2. Code non actif
    • Vérifiez que le code est dans functions.php (thème enfant)
    • Ou vérifiez que le plugin Code Snippets a l'extrait activé
    • Vérifiez les erreurs PHP dans le journal de débogage
  3. Mauvaise devise de base
    • Vérifiez la devise de base dans WooCommerce → Réglages → Général
    • Assurez-vous que WOOCS affiche la même devise de base

Les rapports se chargent lentement

Problème : Analytics met 5 à 10 secondes ou plus à charger Causes :
  • Grande base de données de commandes (10 000+ commandes)
  • De nombreuses conversions de devises nécessaires
  • Ressources serveur limitées
Solutions : Solution 1 : Limiter la plage de dates
// Only convert recent orders (last 12 months)
add_filter('woocommerce_analytics_orders_select_query', function ($results, $args) {
    if (!$results || !isset($results->data)) {
        return $results;
    }
    
    $twelve_months_ago = strtotime('-12 months');
    
    foreach ($results->data as $key => $order_data) {
        $order_date = strtotime($order_data['date_created']);
        
        // Skip old orders
        if ($order_date < $twelve_months_ago) {
            continue;
        }
        
        // ... conversion code ...
    }
    
    return $results;
}, 10, 2);
Solution 2 : Réactiver le cache pour des rapports spécifiques Supprimez la ligne de désactivation du cache et videz manuellement le cache si nécessaire. Solution 3 : Utiliser des rapports externes Envisagez des plugins d'analyse dédiés pour les grandes boutiques.

Taux de change non trouvés

Problème : Certaines commandes affichent la devise d'origine, non convertie Cause : Il manque la métadonnée _woocs_order_rate à la commande et WOOCS n'a plus cette devise Solution : Ajouter un mappage de taux par défaut :
function woocs_get_exchange_rate($from_currency, $to_currency) {
    global $WOOCS;
    
    if (!isset($WOOCS) || !$WOOCS) {
        // Fallback rates if WOOCS not available
        $fallback_rates = [
            'EUR' => 1.09,  // EUR to USD
            'GBP' => 1.27,  // GBP to USD
            'CAD' => 0.74,  // CAD to USD
            'AUD' => 0.66,  // AUD to USD
        ];
        
        if (isset($fallback_rates[$from_currency])) {
            return $fallback_rates[$from_currency];
        }
        
        return 1;
    }
    
    $currencies = $WOOCS->get_currencies();
    
    if (isset($currencies[$from_currency]) AND isset($currencies[$to_currency])) {
        $from_rate = floatval($currencies[$from_currency]['rate']);
        $to_rate = floatval($currencies[$to_currency]['rate']);
        
        if ($from_rate > 0) {
            return $to_rate / $from_rate;
        }
    }
    
    return 1;
}

Les conversions semblent erronées

Problème : Les montants convertis ne correspondent pas aux valeurs attendues Vérifiez :
  1. Les taux de change WOOCS sont-ils précis ?
    • Allez dans les paramètres WOOCS
    • Vérifiez que les taux de change sont à jour
    • Mettez à jour les taux si nécessaire
  2. La commande a utilisé un taux différent ?
    • Les commandes utilisent le taux de la date d'achat
    • Pas le taux actuel
    • C'est un comportement correct
  3. La devise de base est-elle correcte ?
    // Add debug to see what's happening
       error_log('Order: ' . $order_id);
       error_log('Currency: ' . $order_currency);
       error_log('Rate: ' . $exchange_rate);
       error_log('Original: ' . $order_data['total_sales']);
       error_log('Converted: ' . ($order_data['total_sales'] * $exchange_rate));
     

Le code casse le site

Problème : Écran blanc ou erreurs après l'ajout du code Cause : Erreur de syntaxe PHP ou conflit Solution :
  1. Accédez au site via FTP
  2. Renommez functions.php en functions.php.backup
  3. Le site récupère
  4. Vérifiez le code pour les erreurs de syntaxe
  5. Vérifiez le journal des erreurs pour un message d'erreur spécifique

Bonnes pratiques

  1. Utiliser un thème enfant
    • Ajoutez toujours le code au thème enfant
    • Les mises à jour du thème parent n'effaceront pas le code
  2. Tester d'abord
    • Ajoutez d'abord le code sur un site de test
    • Vérifiez que les totaux correspondent aux attentes
    • Ensuite, appliquez en production
  3. Surveiller les performances
    • Vérifiez le temps de chargement d'Analytics avant/après
    • Si trop lent, envisagez des optimisations
  4. Maintenir les taux WOOCS à jour
    • Les rapports sont aussi précis que les taux de change
    • Mettez à jour les taux régulièrement
    • Envisagez la fonction de mise à jour automatique
  5. Documenter les modifications
    • Notez quand vous avez ajouté ce code
    • Gardez une sauvegarde de functions.php
    • Facilite le dépannage

Solutions alternatives

Pour les très grandes boutiques

Si vous avez plus de 50 000 commandes et que cette solution est trop lente, envisagez :
  1. Table de base de données personnalisée
    • Stockez les valeurs converties dans une table personnalisée
    • Mettez à jour lors de la passation de la commande
    • Interrogez la table personnalisée pour les rapports
  2. Conversion planifiée
    • Convertissez les commandes quotidiennement via cron
    • Stockez dans les métadonnées de la commande
    • Rapports rapides avec des données pré-converties
  3. Analytique externe
    • Exportez vers Google Analytics avec une gestion correcte des devises
    • Utilisez une plateforme d'analyse e-commerce dédiée
    • Plugins de rapports WooCommerce tiers

Pour les boutiques avec peu de devises

Si vous n'utilisez que 2 à 3 devises, vous pouvez simplifier :
// Hardcoded rates for specific currencies
add_filter('woocommerce_analytics_orders_select_query', function ($results, $args) {
    if (!$results || !isset($results->data)) {
        return $results;
    }
    
    $rates = [
        'EUR' => 1.09,
        'GBP' => 1.27,
        'USD' => 1.00,  // Base currency
    ];
    
    foreach ($results->data as $key => $order_data) {
        $order_id = $order_data['order_id'];
        $order_currency = get_post_meta($order_id, '_order_currency', true);
        
        if (isset($rates[$order_currency])) {
            $rate = $rates[$order_currency];
            $results->data[$key]['total_sales'] = $order_data['total_sales'] * $rate;
            // ... convert other fields
        }
    }
    
    return $results;
}, 10, 2);
C'est plus rapide mais nécessite des mises à jour manuelles des taux.

Résumé

Le problème : WooCommerce Analytics additionne des devises différentes sans les convertir, affichant des totaux incorrects. La solution : Ajouter un code qui convertit toutes les commandes dans la devise de base en utilisant les taux de change de WOOCS. Compromis :
  • ✅ Rapports multi-devises précis
  • ✅ Utilise les taux de change historiques
  • ❌ Rapports 0,5 à 2 secondes plus lents (pas de cache)
  • ❌ Ne convient pas aux très grandes boutiques (50 000+ commandes)
Résultat : WooCommerce Analytics affichera des données de revenus précises avec toutes les commandes converties dans votre devise de base.