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

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

Stork.71

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

Взял решение в самом начале топика и немного переделал, в этом случае практически все тоже самое, что предлагали ранее: в админке есть поле для ввода курса в ручном режиме и корректный вывод цены в различных типах товара (простой, вариативный), включая товары со скидкой. Если цена у товара не стоит, вместо полученного 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

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

Stork.71

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

Взял решение в самом начале топика и немного переделал, в этом случае практически все тоже самое, что предлагали ранее: в админке есть поле для ввода курса в ручном режиме и корректный вывод цены в различных типах товара (простой, вариативный), включая товары со скидкой. Если цена у товара не стоит, вместо полученного 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

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

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