Hello,
we just started using Mergado Product feed to add our products to Google Merchant Center and we noticed incorrect prices in the feed. The feed is available here:
“URL skryta administrátorem”
Upon some checking, it seems that the prices stated in the feed are listed in EUR while the CURRENCY tag states CZK. Unfortunately this is quite significant problem for us at this point.
For multilinguality we are using WPML and their Multicurrency extension.
Additionally, as you can see in the feed, the description of the products contains HTML tags. Is there a way to remove them? Maybe a filter we could use to filter th description ourselves if it§s not supported by the plugin?
Thanks in advance,
Honza
2 Likes
Hello,
Thank you for reaching out to our support. Unfortunately, at this time, WPML is not fully compatible with the Mergado PACK plugin for WooCommerce.
The solution is to disable the automatic generation of the feed by CRON. Instead, generate it manually according to the current WPML language settings (e.g. Czech - generates a Czech feed, Slovak - generates a Slovak feed).
Due to the incomplete compatibility of the plugin with Mergado Pack, we cannot guarantee the correct generation of multicurrency/multilanguage feeds.
Editing data in the feed is made very simple using our Mergado Editor, which also allows for the removal of HTML tags, currency rewriting, and value conversion from CZK to EUR and vice versa.
Mergado Editor is free for 30 days, and afterwards, the price is based on the number of products and possible integrations. See link Pricing | Mergado.com.
Best regards
Mergado PACK support
Hey,
thanks for the swift reply. That’s unfortunate! I guess generating the feed manually will not resolve the currency issues since they are not related to the selected language, right?
Are there any filters I could use to programatically alter the feed? I can imagine I could fetch the prices in correct currency & filter the descriptions.
I am a bit worried that Mergado Editor wouldn’t be such a good idea since the description and prices change over time on the website and I guess those changes would overwrite the modifications done in Mergado Editor, right?
Thanks,
Honza
Unfortunately, there are no filters before the feed generation (at least for now).
However, there are some filters during the generation process of the product feed (ProductFeed.php) in the following order:
- Price changes :
-
If taxes are enabled:
apply_filters('mergado_product_feed__product_prices__taxes_enabled', ['priceWithoutTax' => $wc_priceWithoutTax, 'regularPriceWithoutTax' => $wc_priceRegularWithoutTax], $v['id'], $productObject);
-
If taxes are disabled:
apply_filters('mergado_product_feed__product_prices__taxes_disabled', ['regularPrice' => $priceVat, 'price' => $discountPriceVat], $v['id'], $productObject);
- Product object before insertion to the feed ( ProductFeedItem object with setters and getters ). You can change any product data here.
apply_filters('mergado_product_feed__product', $productFeedItem, $productObject, $parentObject);
Thanks for pointing me towards the filters. That’s exactly what I had in mind! I will share our solution once we’re there, so oher users can use it too.
1 Like
I reached out to the WPML’s support and they recommended a solution that sets the global WCML currency. So I did some digging and I came up with this snippet. Unfortunately, I am failing to see the effect of teh snippet. When I set the currency to EUR, $product->get_price()
still returns price in CZK.
add_filter("wcml_client_currency", function($currency) {
$action = $_GET['action'] ?? $_POST['action'] ?? $_POST['feed'] ?? null;
if($action != 'productCron' && $action != 'ajax_generate_feed') {
return $currency;
}
return 'CZK';
});
So I came up with a filter to modify the prices in the feed items using the hook you suggested. It looks a little clumsy, but so far it seems to work fine:
function mergado_fix_product_price(\Mergado\Feed\Product\ProductFeedItem $feed_item, WC_Product $product) {
$feed_currency = 'CZK';
$price_args = ['qty' => 1];
$feed_item->setCurrency($feed_currency);
if($product->is_on_sale()) {
$price_args['price'] = $product->get_sale_price();
$feed_item->setPriceDiscount(wcml_convert_price(wc_get_price_excluding_tax($product, $price_args), $feed_currency));
$feed_item->setPriceDiscountVat(wcml_convert_price(wc_get_price_including_tax($product, $price_args), $feed_currency));
}
$price_args['price'] = $product->get_regular_price();
$feed_item->setPrice(wcml_convert_price(wc_get_price_excluding_tax($product, $price_args), $feed_currency));
$feed_item->setPriceVat(wcml_convert_price(wc_get_price_including_tax($product, $price_args), $feed_currency));
return $feed_item;
}
add_filter("mergado_product_feed__product", "mergado_fix_product_price", 10, 3);
WPML asked me to pass you message, so you consider joining their support programme and make Mergado compatible with WPML: WPML Compatibility Program – Go Global
Well, just a few seconds after posting the message above, another cron job was triggered and the prices are again in EUR.
I am a bit lost here. Apparently, the logic I implemented is useless and I am failing to see how can I implement the filter for wpml_client_currency
, so it works for cron jobs too.
Well, after half day of debugging, I seem to have a working solution. Currently the script contains a lot of logging to be able to debug the issue in case the feed is still generated with wrong prices. After a few days I would definitely remove those.
function mergado_fix_product_price(\Mergado\Feed\Product\ProductFeedItem $feed_item, WC_Product $product) {
global $woocommerce_wpml;
$wpml_original_currency = $woocommerce_wpml->multi_currency->get_client_currency();
$feed_currency = 'CZK';
$iscron = wp_doing_cron();
$isajax = is_ajax();
error_log("[MERGADO FEED][{$product->get_id()}][ORIGINAL] WCML currency: $wpml_original_currency, price: {$product->get_regular_price()}, sale price: {$product->get_sale_price()}");
error_log("[MERGADO FEED][{$product->get_id()}][ORIGINAL] CRON? $iscron, AJAX? $isajax, action {$_POST['action']}, feed {$_POST['feed']}");
if($woocommerce_wpml->multi_currency->get_client_currency() != $feed_currency) {
error_log("[MERGADO FEED][{$product->get_id()}] Switching currency from $wpml_original_currency to $feed_currency");
$woocommerce_wpml->multi_currency->set_client_currency($feed_currency);
do_action('wcml_switch_currency', $feed_currency);
}
$wpml_temp_currency = $woocommerce_wpml->multi_currency->get_client_currency();
$price_args = ['qty' => 1];
$feed_item->setCurrency($feed_currency);
$product = wc_get_product( $product->get_id() );
error_log("[MERGADO FEED][{$product->get_id()}][REFETCHED] WCML currency: $wpml_temp_currency, price: {$product->get_regular_price()}, sale price: {$product->get_sale_price()}");
if($product->is_on_sale()) {
$price_args['price'] = $product->get_sale_price();
$feed_item->setPriceDiscount(wc_get_price_excluding_tax($product, $price_args));
$feed_item->setPriceDiscountVat(wc_get_price_including_tax($product, $price_args));
error_log("[MERGADO FEED][{$product->get_id()}][FIXING] Sale price: {$feed_item->getPriceDiscount()}, sale price VAT: {$feed_item->getPriceDiscountVat()}");
}
$price_args['price'] = $product->get_regular_price();
$feed_item->setPrice(wc_get_price_excluding_tax($product, $price_args));
$feed_item->setPriceVat(wc_get_price_including_tax($product, $price_args));
error_log("[MERGADO FEED][{$product->get_id()}][FIXING] Regular price: {$feed_item->getPrice()}, regular price VAT: {$feed_item->getPriceVat()}");
$woocommerce_wpml->multi_currency->set_client_currency($wpml_original_currency);
do_action('wcml_switch_currency', $wpml_original_currency);
error_log("[MERGADO FEED][{$product->get_id()}][RESTORED] WCML currency: {$woocommerce_wpml->multi_currency->get_client_currency()}");
return $feed_item;
}
add_filter("mergado_product_feed__product", "mergado_fix_product_price", 10, 3);
This snippet uses WCML’s set_client_currency()
to change the currency globally. After that it is necessary to fetch the product again and the prices will be in correct currency. Since the cron job can be triggered by customer’s activity, it is necessary to set the currency back after fetching the prices.
Give the fact there is no hook to use before the feed is generated and after it is finished, I am using the mergado_product_feed__product
hook, so all this swicthing back and forth is done for every product is not optimal. It would be much more efficient if there was a hook before and after the generation, so the global currency change can be done just once. Is that anything you could consider adding to the plugin?
Thanks,
Honza
1 Like
Hello,
WPML changes the currency value somewhere else than in WooCommerce, from which our plugin takes the currency. Therefore, integration on our part is necessary.
From our previous interactions with WPML, we identified the following functions that should determine which currency is active and correctly set the current one.
use function WPML\Container\make;
public function isMulticurrencyModeActive() : bool
{
return function_exists( 'wcml_is_multi_currency_on' ) && wcml_is_multi_currency_on();
}
public function setActiveCurrency(string $currencyCode) : void
{
make( \WCML_Multi_Currency::class )->set_client_currency($currencyCode);
}
public function getActiveCurrency() : string
{
return make( \WCML_Multi_Currency::class )->get_client_currency();
}
As you proposed, we can add a hook before and after generating the feed, which users can use to make any necessary changes. Afterwards, we can check if our solution works correctly.
Hey there!
That sounds prefect to me. Just a side note - all the prices calculation & setting in my snippet that I shared before are necessary due to the fact that the product needs to be fetched again after changing the curency to get the proper prices. So adding those hooks before and after should make it very simple for WCML users.
Looking forward to the updated plugin!
Best,
Honza
We have added hooks.
Before the start of generating and fetching products: mergado_product_feed__before
After completion (including in case of an error that might interrupt the entire generation): mergado_product_feed__after
They are called in the usual way using add_action
. Please try them and let us know.
Alright! It seems to work flawlessly now. I used the hooks you added to the plugin and the following snippet that basically remembers the original currency and sets the currency to the desired ones before generating the feed and reverts the steps once the feed is generated.
class JagaiaMergadoFeedPricesFix {
private $original_currency;
public function __construct(private $feed_currency) {}
public function switch_to_feed_currency() {
global $woocommerce_wpml;
$this->original_currency = $woocommerce_wpml->multi_currency->get_client_currency();
$this->wcml_switch_currency($this->feed_currency);
}
public function switch_to_original_currency() {
$this->wcml_switch_currency($this->original_currency);
}
private function wcml_switch_currency($to) {
global $woocommerce_wpml;
if($to != $woocommerce_wpml->multi_currency->get_client_currency()) {
error_log("Mergado feed fix switching currency to {$to}");
$woocommerce_wpml->multi_currency->set_client_currency($to);
}
}
}
$mergado_feed_prices_fix = new JagaiaMergadoFeedPricesFix('CZK');
add_action("mergado_product_feed__before", [$mergado_feed_prices_fix, 'switch_to_feed_currency']);
add_action("mergado_product_feed__after", [$mergado_feed_prices_fix, 'switch_to_original_currency']);
It works well in our test environment. I hope the feeds will be flawless from now on!
1 Like