• Никакой политики на форуме. Иначе - бан!
  • Вопрос без рабочей ссылки на проблему считается риторическим. Без ссылки и скриншота - провокацией!
  • Темы озаглавленные с маленькой буквы или капсом удаляются без предупреждения!

Автоматический пересчет цен по курсу

Stork.71

Гуру
Местный
Всем доброго дня!

Взял решение в самом начале топика и немного переделал, в этом случае практически все тоже самое, что предлагали ранее: в админке есть поле для ввода курса в ручном режиме и корректный вывод цены в различных типах товара (простой, вариативный), включая товары со скидкой. Если цена у товара не стоит, вместо полученного 0 выводим пустоту:

PHP:
//Получаем значения, которые вводит пользователь в отдельной функции
function prime_value_kurs() {
    $kurs = get_option( 'woocommerce_set_kurs', 1 );
    return $kurs;
}

// Типы товара simple, grouped and external
add_filter('woocommerce_product_get_price', 'prime_change_rprice', 99, 2 );
add_filter('woocommerce_product_get_regular_price', 'prime_change_rprice', 99, 2 );

// Тип товара Variations
add_filter('woocommerce_product_variation_get_regular_price', 'prime_change_rprice', 99, 2 );
add_filter('woocommerce_product_variation_get_price', 'prime_change_rprice', 99, 2 );

//Производим пересчет значения
function prime_change_rprice($price,$product) {
    $price = (int)$price * prime_value_kurs();
    if ($price == 0) {
        echo $price='';
        return $price;
    }
    else {
        return $price;
    }
}

/** Добавляем в админку поле для настройки курса **/
add_filter( 'woocommerce_general_settings', 'add_a_setting_kurs' );

function add_a_setting_kurs( $settings ) {

$updated_settings = array();

  foreach ( $settings as $section ) {

    if ( isset( $section['id'] ) && 'pricing_options' == $section['id'] &&
       isset( $section['type'] ) && 'sectionend' == $section['type'] ) {

      $updated_settings[] = array(

        'title'        => 'Курс валюты',
        'desc'         => 'Курс валюты учета по отношению к валюте, которая отображается посетителю',
        'id'           => 'woocommerce_set_kurs',
        'type'         => 'text',
        'css'          => 'width:70px;',
        'default'      => '1',
        'desc_tip'     => false,
      );
    }
    $updated_settings[] = $section;
  }

  return $updated_settings;
}

Пример работы (админка):

http://joxi.ru/vAWOLYEt141nDA

На фронте:

http://joxi.ru/ZrJkdqxT979Opm

@panteradiab,
Если все работает правильно - то ура, наконец-то нашелся человек, который довел все до ума!
 

Stan1991

Новичок
В комментариях есть жалобы на некорректную работу со скидками, а также с неокругленными ценами. Сам не ставил, не пробовал.
Есть ряд сложностей, чтоб округлял нужно поставить запятую (по умолчанию стоит точка в настройках WooCommerce), также он тупит с ценами в вариативных товарах (не умножает на курс). Но для простых задач - самое то.
 

Stork.71

Гуру
Местный
Есть ряд сложностей, чтоб округлял нужно поставить запятую (по умолчанию стоит точка в настройках WooCommerce), также он тупит с ценами в вариативных товарах (не умножает на курс). Но для простых задач - самое то.
для простых задач еще на первой страницы этого топика есть код. С ним как раз и была проблема в работе с вариативными, распродажами и т.д.
 

JingoJohn

Новичок
Всем доброго дня!

Взял решение в самом начале топика и немного переделал, в этом случае практически все тоже самое, что предлагали ранее: в админке есть поле для ввода курса в ручном режиме и корректный вывод цены в различных типах товара (простой, вариативный), включая товары со скидкой. Если цена у товара не стоит, вместо полученного 0 выводим пустоту:

PHP:
//Получаем значения, которые вводит пользователь в отдельной функции
function prime_value_kurs() {
    $kurs = get_option( 'woocommerce_set_kurs', 1 );
    return $kurs;
}

// Типы товара simple, grouped and external
add_filter('woocommerce_product_get_price', 'prime_change_rprice', 99, 2 );
add_filter('woocommerce_product_get_regular_price', 'prime_change_rprice', 99, 2 );

// Тип товара Variations
add_filter('woocommerce_product_variation_get_regular_price', 'prime_change_rprice', 99, 2 );
add_filter('woocommerce_product_variation_get_price', 'prime_change_rprice', 99, 2 );

//Производим пересчет значения
function prime_change_rprice($price,$product) {
    $price = (int)$price * prime_value_kurs();
    if ($price == 0) {
        echo $price='';
        return $price;
    }
    else {
        return $price;
    }
}

/** Добавляем в админку поле для настройки курса **/
add_filter( 'woocommerce_general_settings', 'add_a_setting_kurs' );

function add_a_setting_kurs( $settings ) {

$updated_settings = array();

  foreach ( $settings as $section ) {

    if ( isset( $section['id'] ) && 'pricing_options' == $section['id'] &&
       isset( $section['type'] ) && 'sectionend' == $section['type'] ) {

      $updated_settings[] = array(

        'title'        => 'Курс валюты',
        'desc'         => 'Курс валюты учета по отношению к валюте, которая отображается посетителю',
        'id'           => 'woocommerce_set_kurs',
        'type'         => 'text',
        'css'          => 'width:70px;',
        'default'      => '1',
        'desc_tip'     => false,
      );
    }
    $updated_settings[] = $section;
  }

  return $updated_settings;
}

Пример работы (админка):

http://joxi.ru/vAWOLYEt141nDA

На фронте:

http://joxi.ru/ZrJkdqxT979Opm

@panteradiab,
Привет!
У меня почему-то на вариативных товарах пересчет не происходит. Работает только с простым товаром.
 

Crab

Новичок
Немного доработал решение.
Можно задать от курса какой валюты нужно наценивать, доступно USD и EUR.
Сам курс берется с сайта ЦБ РФ и соответствует последнему официальному курсу ЦБ.
Чтобы постоянно не запрашивать курс сайта ЦБ он кешируется.
Можно указать время кеширования в минутах.

Для использования вставить код в functions.php своей темы
PHP:
add_filter('woocommerce_get_price', 'my_woocommerce_get_price',100,2);
function my_woocommerce_get_price($price, $_product) {
    // параметры ------------------------------------
    $kurs_base                 = 58; // фиксированный базовый курс валюты
    $kurs_current             = 60; // текущий курс валюты по умолчанию
    $kurs_cb = get_currency_cb('EUR'); // получить курс EUR
    // $kurs_cb = get_currency_cb('USD'); // получить курс USD
    // --------------------------------------------------

    $kurs_base = ($kurs_base <= 0) ? 1 : $kurs_base;
    $kurs_current = ($kurs_cb['kurs'] <= 0) ? $kurs_current : $kurs_cb['kurs'];
    $new_price = $price * ($kurs_current / $kurs_base);

    return $new_price; // новая цена
}
function get_currency_cb($code_valute = 'USD', $time_cash = '60' ) {
    // параметры -------------------;
    if ($code_valute != 'USD' && $code_valute != 'EUR') $code_valute = 'USD';
    if ($time_cash <= 0) $time_cash        = 60;         // время кеширования в минутах
    // ------------------------------

    $name_cash         = 'cash_kurs_cb';
    $cached = get_transient($name_cash);
    if ($cached !== false && $cached['code'] == $code_valute) {
        $kurs_cb = $cached;
        return $kurs_cb;
    }
    else {
        libxml_use_internal_errors(true);
        $kurs_cb_xml = simplexml_load_file("http://www.cbr.ru/scripts/XML_daily.asp");
        if ($kurs_cb_xml === false) {
            echo "Ошибка загрузки XML\n";
            foreach(libxml_get_errors() as $error) {
                echo "\t", $error->message;
            }
            $kurs_cb = $cached;
            return $kurs_cb;
        }    
        else
        {
            foreach ($kurs_cb_xml->Valute as $valute) {
                if ((string)$valute->CharCode == $code_valute) {
                    $kurs_cb['date'] = (string)$kurs_cb_xml['Date'];
                    $kurs_cb['kurs'] = (string)$valute->Value;
                    $kurs_cb['code'] = $code_valute;     
                    break;
                }
            }
            $kurs_cb['kurs'] = round(str_replace(',','.',$kurs_cb['kurs']),2);
            set_transient($name_cash, $kurs_cb, MINUTE_IN_SECONDS * $time_cash);
            return $kurs_cb;
        }
    }
}
Любые замечания и предложения приветствуются.
В дальнейшем оформлю в виде плагина.

Доброго дня.
Отличное решение, отлично работает)))
Одна маленькая проблемка только: иногда выдает ошибку загрузки XML
Если сбросить кэш, проблема устраняется
Можете посоветовать, как решить эту проблему?
 

Markiz

Новичок
Доброго дня.
Отличное решение, отлично работает)))
Одна маленькая проблемка только: иногда выдает ошибку загрузки XML
Если сбросить кэш, проблема устраняется
Можете посоветовать, как решить эту проблему?
Здравствуйте! А какие настройки необходимо выставить в админке, что-то не пойму. Код вставил, но никаких изменений ))) И есть ли решение про ошибку загрузки XML? СПАСИБО!!!
 

Darindacafe

Новичок
Здравствуйте! А какие настройки необходимо выставить в админке, что-то не пойму. Код вставил, но никаких изменений ))) И есть ли решение про ошибку загрузки XML? СПАСИБО!!!
Добрый день. Прошу прощения за долгий ответ - давно не заходил на форум.
К сожалению, решения пока не знаю - периодически выскакивает ошибка. Сам я в этом недостаточно разбираюсь, а автор не отвечает. Если узнаю - обязательно поделюсь! (надеюсь, что и другие участники обсуждения)
В админке никаких настроек не делал.
Поскольку код не работал, я его немного упростил (возможно, в чем-то как раз и сделал ошибку, но он хотя бы нормально заработал...) и вставил
в function.php, а в магазине прописал цены в USD. За исключением вышеназванной ошибки работает отлично)))

Вот упрощенная версия этого кода (если кто-то укажет на ошибку, буду благодарен))

add_filter('woocommerce_get_price', 'my_woocommerce_get_price',100,2);
function my_woocommerce_get_price($price, $_product) {
// параметры ------------------------------------
$kurs_cb = get_currency_cb('USD'); // получить курс USD
// --------------------------------------------------

$kurs_current = ($kurs_cb['kurs'] <= 0) ? $kurs_current : $kurs_cb['kurs'];
$new_price = $price * $kurs_current;

return $new_price; // новая цена
}
function get_currency_cb($code_valute = 'USD' ) {

$kurs_cb_xml = simplexml_load_file("http://www.cbr.ru/scripts/XML_daily.asp");
if ($kurs_cb_xml === false) {
$kurs_cb = 70;
return $kurs_cb;
}
{
foreach ($kurs_cb_xml->Valute as $valute) {
if ((string)$valute->CharCode == $code_valute) {
$kurs_cb['date'] = (string)$kurs_cb_xml['Date'];
$kurs_cb['kurs'] = (string)$valute->Value;
$kurs_cb['code'] = $code_valute;
break;
}
}
$kurs_cb['kurs'] = round(str_replace(',','.',$kurs_cb['kurs']),2);
return $kurs_cb;
}
}
 

Markiz

Новичок
Добрый день. Прошу прощения за долгий ответ - давно не заходил на форум.
К сожалению, решения пока не знаю - периодически выскакивает ошибка. Сам я в этом недостаточно разбираюсь, а автор не отвечает. Если узнаю - обязательно поделюсь! (надеюсь, что и другие участники обсуждения)
В админке никаких настроек не делал.
Поскольку код не работал, я его немного упростил (возможно, в чем-то как раз и сделал ошибку, но он хотя бы нормально заработал...) и вставил
в function.php, а в магазине прописал цены в USD. За исключением вышеназванной ошибки работает отлично)))

Вот упрощенная версия этого кода (если кто-то укажет на ошибку, буду благодарен))

add_filter('woocommerce_get_price', 'my_woocommerce_get_price',100,2);
function my_woocommerce_get_price($price, $_product) {
// параметры ------------------------------------
$kurs_cb = get_currency_cb('USD'); // получить курс USD
// --------------------------------------------------

$kurs_current = ($kurs_cb['kurs'] <= 0) ? $kurs_current : $kurs_cb['kurs'];
$new_price = $price * $kurs_current;

return $new_price; // новая цена
}
function get_currency_cb($code_valute = 'USD' ) {

$kurs_cb_xml = simplexml_load_file("http://www.cbr.ru/scripts/XML_daily.asp");
if ($kurs_cb_xml === false) {
$kurs_cb = 70;
return $kurs_cb;
}
{
foreach ($kurs_cb_xml->Valute as $valute) {
if ((string)$valute->CharCode == $code_valute) {
$kurs_cb['date'] = (string)$kurs_cb_xml['Date'];
$kurs_cb['kurs'] = (string)$valute->Value;
$kurs_cb['code'] = $code_valute;
break;
}
}
$kurs_cb['kurs'] = round(str_replace(',','.',$kurs_cb['kurs']),2);
return $kurs_cb;
}
}
Привет! Благодраю за ответ! Сделал при помощи этого плагина
WooCommerce Multiple Currencies
Есть в сети свежий. Отключил весь функционал, оставил только пересчет валюты. Единственное, что товары необходимо размещать в валюте, автоматически бедт идти пересчет в указанные деньги (мне нужны рубли). Затестил, работает. Сайт с нуля, поэтому пока буду добавлять товары. Если будет инфа, дайте знать. Отличного творчества!
 

N1k0lay

Новичок

tulin.ilya

Новичок
Всем привет! Надеюсь за темой кто-нибудь следит.

У меня товар в магазине имеет закупочную цену в евро и долларах. Соответственно продаю его в нац. валюте. Нужен был плагин или код, как изменять цену товаров с определенным тэгом. Для этого воспользовался следующим:

PHP:
// Конвертирование цен на товары из EUR и USD

add_filter('woocommerce_get_price', 'customPrice', 10, 2); // Изменяем цену

add_filter('woocommerce_variation_prices_price', 'customPrice', 10, 2); // Изменяем цену у вариативного товара

function customPrice($price, $product)
{
    // Конвертируем цены только у товаров имеющих тег 'usd'
    if (has_term('USD', 'product_tag', $product->id)) {
        $kurs_cb_USD = 63.08; // Курс валюты
        $price = $price * $kurs_cb_USD;
    }
     // Конвертируем цены только у товаров имеющих тег 'eur'
     if (has_term('EUR', 'product_tag', $product->id)) {
        $kurs_cb_EUR = 71.82; // Курс валюты
        $price = $price * $kurs_cb_EUR;
    }
    return $price;
}

Подскажите как к этому прикрутить автообновление курса валют. Пытался скрестить то что есть на первой странице, ничего не вышло. То что писал при скрещивании не сохранил.
 

ВиталийВВ

Новичок
Добрый день. Прошу прощения за долгий ответ - давно не заходил на форум.
К сожалению, решения пока не знаю - периодически выскакивает ошибка. Сам я в этом недостаточно разбираюсь, а автор не отвечает. Если узнаю - обязательно поделюсь! (надеюсь, что и другие участники обсуждения)
В админке никаких настроек не делал.
Поскольку код не работал, я его немного упростил (возможно, в чем-то как раз и сделал ошибку, но он хотя бы нормально заработал...) и вставил
в function.php, а в магазине прописал цены в USD. За исключением вышеназванной ошибки работает отлично)))

Вот упрощенная версия этого кода (если кто-то укажет на ошибку, буду благодарен))

add_filter('woocommerce_get_price', 'my_woocommerce_get_price',100,2);
function my_woocommerce_get_price($price, $_product) {
// параметры ------------------------------------
$kurs_cb = get_currency_cb('USD'); // получить курс USD
// --------------------------------------------------

$kurs_current = ($kurs_cb['kurs'] <= 0) ? $kurs_current : $kurs_cb['kurs'];
$new_price = $price * $kurs_current;

return $new_price; // новая цена
}
function get_currency_cb($code_valute = 'USD' ) {

$kurs_cb_xml = simplexml_load_file("http://www.cbr.ru/scripts/XML_daily.asp");
if ($kurs_cb_xml === false) {
$kurs_cb = 70;
return $kurs_cb;
}
{
foreach ($kurs_cb_xml->Valute as $valute) {
if ((string)$valute->CharCode == $code_valute) {
$kurs_cb['date'] = (string)$kurs_cb_xml['Date'];
$kurs_cb['kurs'] = (string)$valute->Value;
$kurs_cb['code'] = $code_valute;
break;
}
}
$kurs_cb['kurs'] = round(str_replace(',','.',$kurs_cb['kurs']),2);
return $kurs_cb;
}
}

Вот этот исправленный вариант заработал на ура!!!!!! (зарегистрировался специально чтоб сказать СПАСИБО!!!) Другие плагины все как то не так работают, то тут то там какие то косяки!
Единственное что тут заметил - при просмотре с телефона цена товара показывается без обозначения валюты (без значка "Руб"). в броузере и в эмуляции моблльника - все супер, а именно в мобильном телефоне - ой.
В чем может быть причина?
 

MTVen

Новичок
Хочу представить свой допиленный вариант, я пробовал то, что скидывали выше, но ценник менялся лишь для страницы магазина и страницы товара, в корзине и поиске ценник оставался старый, какой бы фильтр я не привязывал.

В итоге просто скачал плагин Currency per product, у которого есть вроде все нужные мне настройки в бесплатном варианте (валюта только одна, но мне больше и не надо) и воспользовался его параметром alg_wc_cpp_exchange_rate_1 для обновления курса автоматически с помощью представленного выше кода. В общем вот что получилось:

В wp-config добавляем строки:
Код:
// параметр для автоматического обновления курса валюты плагина Currency per product
define('CPP_EXCHANGE_RATE_OPTION', 'alg_wc_cpp_exchange_rate_1');

В functions.php:
Код:
    // получение курса валюты (нужная валюта передаётся в виде параметра code_valute, по умолчанию 'EUR') с сайта ЦБ РФ
    function get_CB_currency($code_valute = 'EUR', $exRate_koef = 1,  $exRate_add = 0) {

        $exRate_cb_xml = simplexml_load_file("https://www.cbr-xml-daily.ru/daily_utf8.xml");
        
        $exRate_default = 90;
        
        if ($exRate_cb_xml === false) {
            return $exRate_default;
        } else {
            foreach ($exRate_cb_xml->Valute as $valute) {
                if ((string)$valute->CharCode == $code_valute) {
                    $exRate_cb['date'] = (string)$exRate_cb_xml['Date'];
                    $exRate_cb['exRate'] = (string)$valute->Value;
                    $exRate_cb['code'] = $code_valute;
                    break;
                }
            }
            $exRate_cb['exRate'] = round(str_replace(',','.',$exRate_cb['exRate']),2);
            
            // проверяем актуальный курс на валидное значение
            $exRate_current = ($exRate_cb['exRate'] <= 0) ? $exRate_default : $exRate_cb['exRate'];
            
            // добавляем модификаторы exRate_koef и exRate_add к курсу ЦБ РФ
            $exRate_current = $exRate_current * $exRate_koef  + $exRate_add;
            
            return $exRate_current;
            
        }
    }
    
    // выставляем вручную параметр курса для плагина Currency per product (через параметр CPP_EXCHANGE_RATE_OPTION, см wp-config.php)
    function set_currency_CPP($current_currency = 90) {
        
        // для плагина нужно перевести курс ЕВР/РУБ в РУБ/ЕВР
        $exRate_rev = 1/get_CB_currency('EUR', 1.1, 1.5);
        update_option(CPP_EXCHANGE_RATE_OPTION, $exRate_rev);
    }
    
    // добавляем action для привязки в crone
    add_action('update_currency_manualy', 'set_currency_CPP');

Ну и я создал crone event, с помощью плагина WP Control, куда передаём имя хука "update_currency_manualy" (с помощью этого плагина очень удобно настраивать периодичность обновления, а заодно обновлять его вручную, в случае резких перепадов курса), после чего ценники отлично отображаются.

:) надеюсь кому-то это поможет так же как и сообщения выше помогли мне.
 
Сверху Снизу