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

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

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

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

searchingman

Гуру
Местный
#4
Спасибо за ответ, да этот плагин встречал, но хотел узнать нет ли другого решения? Может не готового а примера.
Небольшой пример по изменению цены от курса.
Код нужно вставить в 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);
 
#5
Небольшой пример по изменению цены от курса.
Код нужно вставить в 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);
оооо, это походу то что нужно, спасибо большое :)
 
#6
Блин, как актуально! Только хотел подобный вопрос задать. :) Этот код решает зависимость цен в магазине от курса валюты? Т.е. если курс понижается/повышается, цены в магазине соответственно индексируются?
 

searchingman

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

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

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

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

searchingman

Гуру
Местный
#11
Уф. Сейчас у меня цены в рублях. Получается цены нужно перевести в доллары, чтобы весь этот механизм заработал?
Не могу сложить пазл, если сейчас у нас цены в рублях, как мы поставим зависимость от курса валюты, чтобы цены моментально индексировались?
Можно ничего не переводить.
Тогда будет так.
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

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

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

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

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

searchingman

Гуру
Местный
#14
У меня на сайте цены округленные до целых, но доллар буду забивать дробный. Я в 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

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

searchingman

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

searchingman

Гуру
Местный
#17
Немного доработал решение.
Можно задать от курса какой валюты нужно наценивать, доступно 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

Гуру
Местный
#18
ууупс
попробовал на практике, причем самый первый, базовый вариант. Работает странно.
На простых товарах - вместо зачеркнутой цены без скидки и цены со скидкой, выводится только новая цена (расчтывается (индексируется) вроде правильно).
На вариативных товарах выводятся сначала зачеркнутая старая цена без учета индексирования на курс, потом новая цена с учетом индексирования, вот так:
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

Гуру
Местный
#19
ууупс
попробовал на практике, причем самый первый, базовый вариант. Работает странно.
На простых товарах - вместо зачеркнутой цены без скидки и цены со скидкой, выводится только новая цена (расчтывается (индексируется) вроде правильно).
На вариативных товарах выводятся сначала зачеркнутая старая цена без учета индексирования на курс, потом новая цена с учетом индексирования, вот так:
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

Гуру
Местный
#20
а я параллельно экспериментирую в другом направлении.
Динамический курс рубля с сайта ЦБ РФ не подходит, поэтому лучше будем вводить курс вручную, причем в красивое поле в админке (в разделе "опции валюты" на странице общих настроек 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;

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