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

Woocommerce, каждому товару своя валюта

kvanton11

Новичок
@Alexodiy,
Спасибо большое за код, очень понравился.
А у кого нибудь есть код, что бы и на вариативные товары распространялась другая валюта?
 

Kristian

Новичок
Добрый день! Скрипт работает но почему-то с задержкой. Обновляет цены минут через 5. Писали вроде как что надо отключить кэш, но в данном случае непонятно как и что отключат. Пробывал отключать с помощью плагинов, перепробовал несколько штук - не помогло. В общем как исправить задержку? .... заранее спасибо
 
Последнее редактирование:

ВиталийВВ

Новичок
Подниму тему.
Попробовал новый подход. связку плагина:
Currency per Product for WooCommerce
и плагина, описанного тут: https://blog.shikarno.net/vnutrennij-kurs-valyut-v-magazine-na-woocommerce-avtoobnovlenie-s-cbr-ru
на мой взгляд работает почти идеально.
Происходит и пересчет валют, и курс с ЦБ и вариативный товар работает. и все это бесплатно.
Единственный минус - кроме рублевого товара доступен только еще одна валюта (н-р доллар или евро)
 

24andrey24

Новичок
Ребята, это конечно все хорошо и замечательо... я использовал код из это темы, немного переделал, вот что получилось

PHP:
function wc_rubprice_product_field() {
woocommerce_wp_text_input( array( 'id' => '_rub_price', 'class' => 'wc_input_price short', 'label' => __( 'RUB', 'woocommerce' ) ) );
}
add_action( 'woocommerce_product_options_pricing', 'wc_rubprice_product_field' );


add_action( 'woocommerce_product_options_general_product_data', 'woo_add_custom_general_fields' );
add_action( 'woocommerce_process_product_meta', 'woo_add_custom_general_fields_save' );

function woo_add_custom_general_fields() {

  global $woocommerce, $post;

  echo '<div class="options_group">';

woocommerce_wp_text_input(
    array(
        'id'          => '_nacenka',
        'label'       => __( 'Наценка в %', 'woocommerce' ),
        'placeholder' => '50',
        'desc_tip'    => 'true',
        'description' => __( 'Введите наценку в процентах без символа "%". Скрипт прибавит % к общей сумме. Напоминаем, что цена формируется именно к полю "Базовая цена ( руб.)", а валюта высчитывается по курсу ЦБ России', 'woocommerce' )
    )
);
  echo '</div>';
   
}


function wc_usdprice_product_field() {
woocommerce_wp_text_input( array( 'id' => '_usd_price', 'class' => 'wc_input_price short', 'label' => __( 'USD', 'woocommerce' ), 'desc_tip'    => 'true', 'description' => __( 'Высчитывается по курсу ЦБ России если поле заполнено', 'woocommerce' ) ) );
}
add_action( 'woocommerce_product_options_pricing', 'wc_usdprice_product_field' );


function wc_europrice_product_field() {
woocommerce_wp_text_input( array( 'id' => '_euro_price', 'class' => 'wc_input_price short', 'label' => __( 'EUR', 'woocommerce' ), 'desc_tip'    => 'true', 'description' => __( 'Высчитывается по курсу ЦБ России если поле заполнено', 'woocommerce' )  ) );
}
add_action( 'woocommerce_product_options_pricing', 'wc_europrice_product_field' );

// Сохранить наценку
function woo_add_custom_general_fields_save( $post_id ){
   
    // Text Field
    $woocommerce_nacenka = $_POST['_nacenka'];
    if( !empty( $woocommerce_nacenka ) )
        update_post_meta( $post_id, '_nacenka', esc_attr( $woocommerce_nacenka ) );

    $woocommerce_euro_price = $_POST['_euro_price'];
    if ( ( $_POST['_euro_price'] ) ) {
    if ( is_numeric( $_POST['_euro_price'] ) )
    update_post_meta( $post_id, '_euro_price', $_POST['_euro_price'] );
    } else delete_post_meta( $post_id, '_euro_price' );

    $woocommerce_usd_price = $_POST['_usd_price'];
    if ( ( $_POST['_usd_price'] ) ) {
    if ( is_numeric( $_POST['_usd_price'] ) )
    update_post_meta( $post_id, '_usd_price', $_POST['_usd_price'] );
    } else delete_post_meta( $post_id, '_usd_price' );

    $woocommerce_usd_price = $_POST['_rub_price'];
    if ( ( $_POST['_rub_price'] ) ) {
    if ( is_numeric( $_POST['_rub_price'] ) )
    update_post_meta( $post_id, '_rub_price', $_POST['_rub_price'] );
    } else delete_post_meta( $post_id, '_rub_price' );
   
}

function wc_myprice_show() {
global $product, $post;
// Ничего не предпринимаем для вариативных товаров
//if ( $product->product_type <> 'variable' ) {
$RUB = get_post_meta( $product->get_id(), '_rub_price', true );
$USD = get_post_meta( $product->get_id(), '_usd_price', true );
$EUR = get_post_meta( $product->get_id(), '_euro_price', true );
$nacenka = get_post_meta( $product->get_id(), '_nacenka', true );
// woocommerce_price( $RUB )

// Формируем сегодняшнюю дату
    $date = date("d/m/Y");
    // Формируем ссылку
    $link = "http://www.cbr.ru/scripts/XML_daily.asp?date_req=$date";
    // Загружаем HTML-страницу
    $fd = fopen($link, "r");
    $text="";
    if (!$fd) echo "";
    else
    {
      // Чтение содержимого файла в переменную $text
      while (!feof ($fd)) $text .= fgets($fd, 4096);
    }
    // Закрыть открытый файловый дескриптор
    fclose($fd);
   
  // Получаем текущие курсы валют в rss-формате с сайта www.cbr.ru
  $content = $text;
  // Разбираем содержимое, при помощи регулярных выражений
  $pattern = "#<Valute ID=\"([^\"]+)[^>]+>[^>]+>([^<]+)[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>([^<]+)[^>]+>[^>]+>([^<]+)#i";
  preg_match_all($pattern, $content, $out, PREG_SET_ORDER);
  $dollar = "";
  $euro = "";
  foreach($out as $cur)
  {
    if($cur[2] == 840) $dollar = str_replace(",",".",$cur[4]);
    if($cur[2] == 978) $euro   = str_replace(",",".",$cur[4]);
  }

  // проверяем заполнено ли поле, если да, то умножаем на курс и записываем в $custom_price
if (($RUB != "") && ($RUB != 0)) {
    $custom_price = $RUB;
}
if (($USD != "") && ($USD != 0)) {
    $custom_price = $USD * $dollar;
}
if (($EUR != "") && ($EUR != 0)) {
    $custom_price = $EUR * $euro;
}
ceil($custom_price); // округляем до сотых

$regular_price = get_post_meta($post->ID, '_price', true); //получаем текущую цену товара


$proc = $nacenka; // количество процентов
$number = $custom_price; // число к которому надо добавить проценты
$proc = $number/100*$proc; // высчитываем процент от числа
$result = $number + $proc; // суммируем число с процентами от этого числа
ceil($result); // округляем до целого



//if ($regular_price != $ $custom_price) { // проверяем совпадает ли текущая цена с нашей новой, если нет, то перезаписываем её
update_post_meta( $post->ID, '_regular_price', $result );
update_post_meta( $post->ID, '_price', $result );  

//можно вывести нашу custom_price для проверки
// echo '<div class="woocommerce_msrp">';
// _e( 'RUB : ', 'woocommerce' );
// echo '<span class="woocommerce-rrp-price RUB">' . $RUB . '</span>';
// echo '</div>';

// echo '<div class="woocommerce_msrp">';
// _e( 'USD : ', 'woocommerce' );
// echo '<span class="woocommerce-rrp-price USD">' . $USD . '</span>';
// echo '</div>';

// echo '<div class="woocommerce_msrp">';
// _e( 'EUR : ', 'woocommerce' );
// echo '<span class="woocommerce-rrp-price EUR">' . $EUR . '</span>';
// echo '</div>';
}

//}
//}


add_action( 'woocommerce_single_product_summary', 'wc_myprice_show', 5 );
add_action( 'woocommerce_after_shop_loop_item_title', 'wc_myprice_show' );

Но при включенных add_action:

PHP:
add_action( 'woocommerce_single_product_summary', 'wc_myprice_show', 5 );
add_action( 'woocommerce_after_shop_loop_item_title', 'wc_myprice_show' );

Страница грузится более 8 секунд, особенно в категориях. А все почему? А потому, что цена генерируется в момент загрузки страницы, а в категориях вообще на все шаги цикла делаются запросы. Как сделать так, чтобы страница при загрузке не лагала? быть может сгенерировать файл кэша, а из его уже выводить цены? Генерацию файла можно сделать по кнопке к примеру... есть у кого идеи?
Добрый день! Подскажите пожалуйста как сделать чтобы дополнительные поля валют отображалась в вариативных товарах.
 

Blaex

Новичок

Да, связка вроде как отличная. Но может поможет кто сделать такую схемку для Беларуси?

Сколько искал альтернатив, ничего толком не подходит.
 

neoff

Опытный

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

Тем кто хочет сменить источник получения курса надо будет немного изменить функцию get_CB_currency и вставить нужные API.

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

XMSilverLine

Новичок
Добрый день...
Необходим не пересчет цены вариавтивного товара... а возможность указать его изначально в другой валюте.
Это возможно?
 

XMSilverLine

Новичок
Добрый день еще раз.
Есть файл .txt с кодом типа
<valute (без ID)>...</valute>
В нем три валюты...
Можно ли брать данные из него?
Всего будет 5 валют...
 

codexjus

Новичок
Здравствуйте, новая версия wp и wc, не работает код на моменте
add_action( 'woocommerce_get_regular_price', 'wc_myprice_show', 10 );
В админке перестает показывать товары, если убрать woocommerce_get_regular_price ошибка пропадает но и цены не меняются. Как исправить?

Подробности ошибки
===================================
Ошибка с типом E_ERROR возникла на строке 278 файла /wp-content/themes/shopys/functions.php. Сообщение об ошибке: Uncaught Error: Call to undefined function split() in /wp-content/themes/shopys/functions.php:278
Stack trace:
#0 [internal function]: wc_myprice_show('2590995')
#1 /wp-includes/class-wp-hook.php(310): call_user_func_array('wc_myprice_show', Array)
#2 /wp-includes/plugin.php(256): WP_Hook->apply_filters('2590995', Array)
#3 /wp-content/plugins/woocommerce/includes/class-wc-deprecated-filter-hooks.php(146): apply_filters_ref_array('woocommerce_get...', Array)
#4 /wp-content/plugins/woocommerce/includes/class-wc-deprecated-filter-hooks.php(133): WC_Deprecated_Filter_Hooks->trigger_hook('woocommerce_get...', Array)
#5 /wp-content/plugins/woocommerce/includes/abstracts/abstract-wc-deprecated-hooks.php(75): WC_Deprecated_Filter_Hooks->handle_deprecated_hook('woocommerce_pro...', 'woocommerce_get.
 
Последнее редактирование:

Alik26

Новичок
попробуйте перед кодом перезаписи цены дописать условие :
Код:
$sale_price = get_post_meta($post->ID, '_sale_price', true);
if (!$sale_price) {
//код перезаписи цены
}
правда могу ошибаться с _sale_price, возможно не то поле или называется по другому))
Нашли решение? У меня такая же проблема, не работает акционная цена. Код не помогает. Или я вставляю не туда? Расскажите подробнее если кто решил проблему
 
Сверху Снизу