Категории форума

Записки CotoДела

Мои записи, как типовые решения разных вопросов с Cotonti

webitproff
webitproff • 18.03.2026 08:58 #496

Как перезаписать цену товара в своей валюте, по актуальному курсу, используя валюту поставщика


Шаг 1. Добавление поля в базу данных

Вам нужно выполнить SQL-запрос в phpMyAdmin или через консоль MySQL.
Запрос:

ALTER TABLE `cot_market` ADD `fieldmrkt_cost_usd` DECIMAL(10,2) NOT NULL DEFAULT '0.00' AFTER `fieldmrkt_costdflt`;

Это добавит новое поле для хранения цены в USD.


Шаг 2. Добавление настроек в конфигурацию модуля Market

Откройте файл modules/market/market.setup.php.
Найдите секцию [BEGIN_COT_EXT_CONFIG] и добавьте туда две строки:

market_rate_value_to_uah=76:string::44.00:
market_for_rate_base_currency_cost_usd=75:string::USD:

После этого зайдите в админку → Управление сайтом → Модули → Market и нажмите "Сохранить", чтобы новые настройки появились в базе.


Шаг 3. Изменение файла functions.php

Откройте modules/market/inc/market.functions.php.

3.1. В функции cot_market_import (примерно строка 80–90) найдите строку с $ritem['fieldmrkt_costdflt'] и сразу после неё добавьте:

$ritem['fieldmrkt_cost_usd'] = cot_import('ritemarketcostusd', $source, 'NUM');

3.2. В функции cot_generate_markettags найдите массив $temp_array (там много строк). После строки с 'COSTDFLT' => ... добавьте:

'COST_USD' => (float)$item_data['fieldmrkt_cost_usd'],
'COST_USD_RAW' => rtrim(rtrim(number_format((float)$item_data['fieldmrkt_cost_usd'], 2, '.', ''), '0'), '.'),
'COST_USD_FORMATTED' => $item_data['fieldmrkt_cost_usd'] > 0 
    ? number_format($item_data['fieldmrkt_cost_usd'], 2, '.', ' ') 
    : '',

Шаг 4. Добавление поля в форму редактирования товара

Откройте modules/market/market.edit.php.

Найдите массив $itemedit_array (там перечислены 'MARKETEDIT_FORM_COSTDFLT' и другие). Рядом с 'MARKETEDIT_FORM_COSTDFLT' добавьте:

'MARKETEDIT_FORM_COST_USD' => cot_inputbox('text', 'ritemarketcostusd', $item['fieldmrkt_cost_usd'], 'size="10"'),

Теперь в шаблоне редактирования (например, market.edit.tpl) вы сможете вывести это поле:

<div class="mb-3">
    <label class="form-label">Цена в UAH (обычная):</label>
    {MARKETEDIT_FORM_COSTDFLT}
</div>
<div class="mb-3">
    <label class="form-label">Цена в USD (закупочная):</label>
    {MARKETEDIT_FORM_COST_USD}
</div>

Шаг 5. Изменение шаблонов вывода цены

Вам нужно заменить блоки, где выводится цена, в трёх файлах:

  • market.tpl (детальная страница товара)
  • market.list.tpl (список товаров)
  • market.index.tpl (индексная страница)

Вставьте этот код вместо существующего блока с ценой:

<!-- IF {MARKET_COSTDFLT} > 0 -->
    <span class="price-label">{PHP.L.market_price_supplier_coverted}</span>
    <p>
        <span class="ms-2 text-success market-price"
              data-usd-price="{MARKET_COST_USD_RAW}"
              data-rate="{PHP.cfg.market.market_rate_value_to_uah}">
            {MARKET_COSTDFLT}
        </span>
    </p>
    {PHP.cfg.market.market_currency}

    <!-- IF {MARKET_COST_USD} > 0 -->
    <div class="text-muted small">
        {PHP.L.market_price_supplier}: {MARKET_COST_USD_FORMATTED} USD
    </div>
    <!-- ENDIF -->
<!-- ENDIF -->

Обратите внимание: data-currency мы убрали, так как валюта выводится отдельно.


Шаг 6. Добавление языковых констант

Откройте языковой файл модуля Market, например modules/market/lang/market.ru.php.
Добавьте в конец (перед закрывающим ?> если есть):

$L['market_price_supplier'] = 'Отпускная цена поставщика';
$L['market_price_supplier_coverted'] = 'Цена в UAH (по курсу USD):';
$L['market_price_converted_label'] = 'Цена в UAH (по курсу USD):';
$L['market_price'] = 'Цена:';

Если какие-то из этих констант уже есть, просто добавьте недостающие.


Шаг 7. Создание файла хука для JavaScript

Создайте новый файл modules/market/market.rc.php (если его нет) и вставьте туда следующий код:

<?php
/* ====================
[BEGIN_COT_EXT]
Hooks=rc
[END_COT_EXT]
==================== */

defined('COT_CODE') or die('Wrong URL');

// Подключаем языковой файл модуля Market, если ещё не загружен
if (!isset($L['market_price_converted_label'])) {
    require_once cot_langfile('market', 'module');
}

global $L, $cfg;

if (cot_module_active('market')) {
    $converted_label = $L['market_price_converted_label'] ?? 'Цена в UAH (по курсу USD):';
    $default_label   = $L['market_price'] ?? 'Цена:';
    $rate            = $cfg['market']['market_rate_value_to_uah'] ?? 44.50;

    $converted_label_js = json_encode($converted_label, JSON_HEX_APOS | JSON_HEX_QUOT);
    $default_label_js   = json_encode($default_label, JSON_HEX_APOS | JSON_HEX_QUOT);
    $rate_js            = json_encode((float)$rate);

    Resources::embedFooter(<<<JS
    document.addEventListener('DOMContentLoaded', function() {
        const convertedLabel = {$converted_label_js};
        const defaultLabel   = {$default_label_js};
        const defaultRate    = {$rate_js};

        document.querySelectorAll('.market-price').forEach(function(el) {
            const usdPrice = parseFloat(el.dataset.usdPrice);
            const rate     = parseFloat(el.dataset.rate) || defaultRate;

            if (!isNaN(usdPrice) && usdPrice > 0 && !isNaN(rate) && rate > 0) {
                const uahPrice = usdPrice * rate;
                const formatted = uahPrice.toLocaleString('ru-RU', {
                    minimumFractionDigits: (uahPrice % 1 !== 0) ? 2 : 0,
                    maximumFractionDigits: 2
                });
                el.innerHTML = formatted;

                const label = el.closest('p, div, span, .fw-bold')?.querySelector('.price-label');
                if (label) {
                    label.textContent = convertedLabel;
                }
            } else {
                const label = el.closest('p, div, span, .fw-bold')?.querySelector('.price-label');
                if (label && label.textContent !== defaultLabel) {
                    label.textContent = defaultLabel;
                }
            }
        });
    });
    JS
    );
}

Этот файл будет автоматически подключаться благодаря хуку rc, и JavaScript встроится в подвал сайта.


Шаг 8. Проверка

  1. Зайдите в админку, откройте любой товар на редактирование – должно появиться поле для ввода цены в USD.
  2. Заполните цену в USD (например, 100) и сохраните товар.
  3. На странице товара вы увидите:
    • Отпускная цена поставщика: 100.00 USD (маленьким текстом)
    • Основная цена (число) будет пересчитана по курсу, например, 4400.00, а валюта (UAH) выведена отдельно.
    • Подпись над ценой изменится на "Цена в UAH (по курсу USD):".
  4. Если поле USD пустое или равно 0, то конвертация не происходит, отображается обычная цена и стандартная подпись "Цена:".

Возможные проблемы и их решение

  • Поле в редактировании не появилось – проверьте, что вы добавили строку в $itemedit_array и что файл market.edit.php сохранён в UTF-8 без BOM.
  • Цена не пересчитывается – откройте консоль браузера (F12) и посмотрите, нет ли ошибок JavaScript. Убедитесь, что у элемента .market-price есть атрибуты data-usd-price и data-rate.
  • Не меняется подпись – проверьте, что языковые константы добавлены и что класс price-label есть у нужного элемента.
  • Курс не применяется – убедитесь, что в настройках модуля Market (market_rate_value_to_uah) задано число (например, 44.50) и что оно доступно через {PHP.cfg.market.market_rate_value_to_uah}.
🗿

🧙‍♂️ Радуйся, странниче добрый и честный! Не понапрасну привела тя стезя в земли сии. Зде бо мужи мудры и искусники дела писменнаго и численнаго, что куют словеса и плетут узоры кода, тайны разгадывают и знанием делятся, летописи множа и ремесло цифровое творя.
⬅️ Аще налево пойдеши — обрящеши грамоты древния, писания старинныя и свитки учения. ⬆️ Аще прямо — слово мудрое и совет от мужей разумеющих, что в деле кодописном искусны, получиши. ➡️ Аще направо — сам в писцы и летописцы внидеши, и в ремесло цифровое, где строки и знаки в дело живое обращаются, слово свое в память веков вложиши.
📝 Не медли же — нареки имя свое, и вниди в чин наш, и стань с нами в братстве, где код есть магия, а строки — заклятия живыя, числом и буквою слово едины суть.
🏰 Не тайно есть собрание сие, и не инициации в нем, но многое сокрыто от пришлых и ступалого, понеже не всякому открывается знание, но токмо ищущим и пребывающим в деле сем.