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

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

hardwaremaster

Новичок
Приветствую! Ребята кто-то знает существует ли такой функционал для автоматического пересчета цен по курсу?

Буду признателен если подскажите.
 

searchingman

Гуру
Местный
Спасибо за ответ, да этот плагин встречал, но хотел узнать нет ли другого решения? Может не готового а примера.
Небольшой пример по изменению цены от курса.
Код нужно вставить в functions.php вашей темы.
PHP:
function my_woocommerce_get_price($price, $_product) {
    $kurs = 58; // курс валюты
    $new_price = $price * $kurs;
    return $new_price; // новая цена
}
add_filter('woocommerce_get_price', 'my_woocommerce_get_price',100,2);
 

hardwaremaster

Новичок
Небольшой пример по изменению цены от курса.
Код нужно вставить в functions.php вашей темы.
PHP:
function my_woocommerce_get_price($price, $_product) {
    $kurs = 58; // курс валюты
    $new_price = $price * $kurs;
    return $new_price; // новая цена
}
add_filter('woocommerce_get_price', 'my_woocommerce_get_price',100,2);

оооо, это походу то что нужно, спасибо большое :)
 

ВладБлад

Опытный
Блин, как актуально! Только хотел подобный вопрос задать. :) Этот код решает зависимость цен в магазине от курса валюты? Т.е. если курс понижается/повышается, цены в магазине соответственно индексируются?
 

searchingman

Гуру
Местный
Блин, как актуально! Только хотел подобный вопрос задать. :) Этот код решает зависимость цен в магазине от курса валюты? Т.е. если курс понижается/повышается, цены в магазине соответственно индексируются?
Это всего лишь пример возможного динамического изменения цен от каких-то параметров.
Хотя возможно сделать, чтобы и курсы автоматом подгружались, н-р, из РБК.
 

hardwaremaster

Новичок
Блин, как актуально! Только хотел подобный вопрос задать. :) Этот код решает зависимость цен в магазине от курса валюты? Т.е. если курс понижается/повышается, цены в магазине соответственно индексируются?

Я пока не вникал, попробовал просто на работоспособность, детально не вникал еще но вроде работает как я хотел, главное что бы цена была везде едина, но вроде на странице товара и в корзине все отлично работает, но не знаю еще какая сумма придет на почту, возможно что придет та что в БД задана, если нет то тогда все вообще отлично!

А фильтр да, работает так что та цена которая в админке к товару задана * на курс, к примеру в админке можно поставить цену в $ и умножать на курс руб. и будет актуальная цена.

Теперь осталось только задать в админке поле для задания курса и все (y)

ну или даже
Хотя возможно сделать, чтобы и курсы автоматом подгружались, н-р, из РБК.
 
  • Like
Реакции: D&B

ВладБлад

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

searchingman

Гуру
Местный
Уф. Сейчас у меня цены в рублях. Получается цены нужно перевести в доллары, чтобы весь этот механизм заработал?
Не могу сложить пазл, если сейчас у нас цены в рублях, как мы поставим зависимость от курса валюты, чтобы цены моментально индексировались?
Можно ничего не переводить.
Тогда будет так.
PHP:
function my_woocommerce_get_price($price, $_product) {
    $kurs             = 58; // фиксированный базовый курс валюты
    $kurs_current     = 60; // текущий курс валюты
    $new_price = $price * ($kurs_current / $kurs);
    return $new_price; // новая цена
}
add_filter('woocommerce_get_price', 'my_woocommerce_get_price',100,2);
Вы фиксируете некий курс для ваших цен, назовем его базовым.
Затем используете текущий курс и уже умножаете на отклонение от базового.
Если отклонение больше 1, то курс увеличился и нужно поднять цену и наоборот.
 

Stork.71

Гуру
Местный
Волшебство! Просто и изящно! (y)

Последнее решение (с базовой стоимостью и базовым курсом) реализовать проще и быстрее, но что потом? При добавлении новых товаров надо будет высчитать для них цену по старому курсу, еще и вспомнить, а какой же курс был пару лет назад, когда на сайт добавился этот код. Можно конечно глянуть в код, но это тоже отнимет время. К тому же при работе кода, при расчетах появляется дополнительное действие, лишняя строчка кода - теряем килобайты и миллисекунды :) . ИМХО лучше воспользоваться первым вариантом, с конвертацией напрямую из долларов, и забить в сайт цены в долларах (воспользовавшись, к примеру, экспортом-импортом CSV), ну и в дальнейшем уже вбивать в карточку товара цену в долларах.
Кстати, для "мгновенной индексации" такое вряд ли поможет. Поисковик же не видит всех этих курсов и вычислений, он видит только конечный результат.

Хочется попросить немножко дополнить код. У меня на сайте цены округленные до целых, но доллар буду забивать дробный. Я в php не шарю, правильно ли я понимаю, мне надо прописать
PHP:
$new_price =  round ($price * $kurs);
, ну или ceil вместо round если хочу округлять до бОльшего, а не по правилам?

Что еще хотелось бы, так это чтобы в админке (например на странице настроек woocommerce сайт/wp-admin/admin.php?page=wc-settings) появилось поле, в котором можно было бы быстро менять этот курс, не лезя в код. То есть сделать $kurs не константой, задаваемой в функции, а брать ее окуда-то из переменных wordpress (предварительно туда занеся). Такая система дополнительно дает возможность повесить где-нибудь на сайте Лэйбл "Курс $: 60.1", который тоже будет ссылаться на эту переменную.
 
Последнее редактирование:

searchingman

Гуру
Местный
У меня на сайте цены округленные до целых, но доллар буду забивать дробный. Я в php не шарю, правильно ли я понимаю, мне надо прописать
PHP:
$new_price =  round ($price * $kurs);
, ну или ceil вместо round если хочу округлять до бОльшего, а не по правилам?
В WooCommerce есть специальная функция wc_get_price_decimals(), которая получает количество знаков после запятой из настроек плагина http://take.ms/cpkrm .
Поэтому более универсально будет так.
PHP:
$decimals = wc_get_price_decimals();
$new_price =  round ($price * $kurs, $decimals);
 

Stork.71

Гуру
Местный
Спасибо!
А woocommerce_get_price по умолчанию (не наша замененная) наверное так и работает: берет обычную цену и округляет ее с учетом wc_get_price_decimals() ? Или там еще есть что-то?
 

searchingman

Гуру
Местный
Спасибо!
А woocommerce_get_price по умолчанию (не наша замененная) наверное так и работает: берет обычную цену и округляет ее с учетом wc_get_price_decimals() ? Или там еще есть что-то?
Да, проверил. В приведенном выше примере не требуется указывать округление, т.к. используется параметр округления из настроек плагина.
 

searchingman

Гуру
Местный
Немного доработал решение.
Можно задать от курса какой валюты нужно наценивать, доступно 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;
        }
    }
}
Любые замечания и предложения приветствуются.
В дальнейшем оформлю в виде плагина.
 
Последнее редактирование:

Stork.71

Гуру
Местный
ууупс
попробовал на практике, причем самый первый, базовый вариант. Работает странно.
На простых товарах - вместо зачеркнутой цены без скидки и цены со скидкой, выводится только новая цена (расчтывается (индексируется) вроде правильно).
На вариативных товарах выводятся сначала зачеркнутая старая цена без учета индексирования на курс, потом новая цена с учетом индексирования, вот так:
177 грн.–197 грн.
1,682 грн.–1,872 грн.
(подчеркивание означает зачеркивание).

Вот код, который я добавлял в functions.php
PHP:
/** Меняем цену товара в соответствии с курсом **/
function my_woocommerce_get_price($price, $_product) {
    $kurs = 10; // курс валюты
    $new_price = $price * $kurs;
    return $new_price; // новая цена
}
add_filter('woocommerce_get_price', 'my_woocommerce_get_price',100,2);
 

searchingman

Гуру
Местный
ууупс
попробовал на практике, причем самый первый, базовый вариант. Работает странно.
На простых товарах - вместо зачеркнутой цены без скидки и цены со скидкой, выводится только новая цена (расчтывается (индексируется) вроде правильно).
На вариативных товарах выводятся сначала зачеркнутая старая цена без учета индексирования на курс, потом новая цена с учетом индексирования, вот так:
177 грн.–197 грн.1,682 грн.–1,872 грн.
(подчеркивание означает зачеркивание).

Вот код, который я добавлял в functions.php
PHP:
/** Меняем цену товара в соответствии с курсом **/
function my_woocommerce_get_price($price, $_product) {
    $kurs = 10; // курс валюты
    $new_price = $price * $kurs;
    return $new_price; // новая цена
}
add_filter('woocommerce_get_price', 'my_woocommerce_get_price',100,2);
Да, действительно для некоторых случаев, как вывод цены с учетом старой цены используются другие функции.
Н-р, для вывода цены с учетом скидки (новой и старой зачеркнутой ) используются функция get_price_html(), которая для вывода использует в том числе и get_price().
Поэтому цены показываются с учетом наценки, но старые цены без учета наценки.
Посмотрю что можно поправить.
 
Последнее редактирование:

Stork.71

Гуру
Местный
а я параллельно экспериментирую в другом направлении.
Динамический курс рубля с сайта ЦБ РФ не подходит, поэтому лучше будем вводить курс вручную, причем в красивое поле в админке (в разделе "опции валюты" на странице общих настроек woocommerce)
Вроде работает (ну, проблемы со старой ценой и распродажами остались).

PHP:
/** Меняем цену товара в соответствии с курсом **/
function my_woocommerce_get_price($price, $_product) {
    // $kurs = 10; // курс валюты
    $kurs = get_option( 'woocommerce_set_kurs', 1 ); // курс валюты, полученный из настроек в админке
    $new_price = $price * $kurs;
    return $new_price; // новая цена
}
add_filter('woocommerce_get_price', 'my_woocommerce_get_price',100,2);

/** Добавляем в админку поле для настройки курса **/
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;

}

(о добавлении в админку новых полей для настроек читал здесь и здесь)

На заметку: чтобы добавить настройку не в секции Валют, а в отдельной, код такой:
PHP:
/** Добавляем в админку поле для настройки курса **/
add_filter( 'woocommerce_general_settings', 'add_a_setting_kurs' );
function add_a_setting_kurs( $settings ) {

    $settings[] = array( 'name' => 'Настройки курса', 'type' => 'title', 'desc' => '', 'id' => 'woocommerce_kurs_settings' );
                   
    $settings[] = array(
        'title'        => 'Курс валюты',
        'desc'         => 'Курс валюты учета по отношению к валюте, которая отображается посетителю интернет-магазина',
        'id'           => 'woocommerce_set_kurs',
        'type'         => 'text',
        'css'      => 'width:70px;',
        'default'    => '1',
        'desc_tip'    => false,
    );

    $settings[] = array( 'type' => 'sectionend', 'id' => 'woocommerce_kurs_settings');

    return $settings;

}
 
Последнее редактирование:
Сверху Снизу