Yandex Metrika
sanches.free

Работа с валютами в Bitrix: CurrencyManager, ORM и модуль Sale

Зачем отдельный модуль

В «1С‑Битрикс» валютные суммы и курсы живут в модуле currency. Его нужно явно подключить до любых вызовов API (в обработчиках, сервисах, консольных скриптах с прологом этого же состава):

\Bitrix\Main\Loader::includeModule('currency');

Для корзины и заказов дополнительно обычно требуется sale; в примерах ниже это подразумевается там, где речь про заказ и позицию корзины.

Список валют для списков и подписей

CurrencyManager::getCurrencyList() возвращает массив «код => подпись» с учётом языковых настроек текущего контекста (удобно для селектов и подсказок в административной части и на витрине):

use Bitrix\Currency\CurrencyManager;

$list = CurrencyManager::getCurrencyList();
// Пример структуры: ['RUB' => 'RUB (Рубль)', 'USD' => '...', ...]

ORM: справочник валют и языковые поля

Таблица b_catalog_currency доступна как \Bitrix\Currency\CurrencyTable. Для подписей на конкретном языке используйте CurrencyLangTable с фильтром по LID и CURRENCY:

use Bitrix\Currency\CurrencyTable;
use Bitrix\Currency\CurrencyLangTable;

$rows = CurrencyTable::getList([
    'select' => ['CURRENCY', 'AMOUNT_CNT', 'AMOUNT', 'SORT', 'BASE', 'CURRENT_BASE_RATE'],
    'order' => ['SORT' => 'ASC'],
]);
while ($row = $rows->fetch()) {
    // сырой набор полей валюты
}

$lang = CurrencyLangTable::getRow([
    'filter' => ['=CURRENCY' => 'USD', '=LID' => LANGUAGE_ID],
    'select' => ['FULL_NAME', 'FORMAT_STRING'],
]);

Курсы

История и текущие значения курсов лежат в CurrencyRateTable (то, что в админке отображается как курсы относительно базовой валюты):

use Bitrix\Currency\CurrencyRateTable;

$rates = CurrencyRateTable::getList([
    'select' => ['*'],
    'order' => ['DATE_RATE' => 'DESC'],
    'limit' => 50,
]);
while ($rate = $rates->fetch()) {
    // CURRENCY, BASE_CURRENCY, RATE_CNT, RATE, DATE_RATE, ...
}

Базовая валюта

Трёхбуквенный код базовой валюты проекта (как задано в настройках модуля Валюты):

$base = \Bitrix\Currency\CurrencyManager::getBaseCurrency();

Заказ и корзина

Уже собранные объекты Sale отдают код валюты без обращения к глобальным настройкам:

// $order — \Bitrix\Sale\Order
$orderCurrency = $order->getCurrency();

// $basketItem — элемент корзины
$itemCurrency = $basketItem->getCurrency();

Так вы не смешиваете «валюту отображения» с произвольными строками из инфоблоков до тех пор, пока сами не решите привести их к коду из CurrencyTable.

Сброс кеша валют

После программного изменения курсов или справочника имеет смысл очистить кеш модуля для нужного языка сайта:

\Bitrix\Currency\CurrencyManager::clearCurrencyCache('ru');

Второй аргумент в актуальных версиях может уточнять код валюты; ориентируйтесь на сигнатуру в вашей сборке модулей.

Практические замечания

  • Для отображения сумм в шаблонах пользуйтесь штатным форматированием модуля валют, а не ручной склейкой символа и числа — так сохраняются правила пробелов и порядок валюта/сумма.
  • При импорте прайсов и обменах следите, чтобы код валюты в данных совпадал с заведённым в справочнике; иначе конвертации и CURRENT_BASE_RATE в каталоге начинают расходиться с ожиданиями.
  • В консольных задачах и агентах не забывайте про инициализацию языка и сайта, если от них зависят getCurrencyList() и языковые поля.

Итог

Минимальный набор для D7: Loader::includeModule('currency'), выборки через CurrencyTable / CurrencyRateTable, быстрые подписи через CurrencyManager::getCurrencyList(), базовая валюта через getBaseCurrency, контекст Sale через getCurrency() у заказа и позиции корзины и сброс кеша после изменений данных.

Не хотите копаться сами?

Починю за 1-3 дня. Без предоплаты — оплата по результату.

15+ лет опыта с 1С-Битрикс · Без предоплаты · 7 дней гарантии