0

I have a fresh Magento 2 setup in my system. I want to add custom currency for my store. I have been following the reference link to add it but I didn't get the result from it.

https://community.magento.com/t5/Magento-2-x-Programming/Adding-Custom-Currency/td-p/28967

Here is the code:

vendor/magento/zendframework1/library/Zend/Locale/Data/en.xml

<currency type="ZZZ">
    <displayName>Custom Currency</displayName>
    <displayName count="one">Custom Currency</displayName>
    <displayName count="other">Custom Currency</displayName>
</currency>

vendor/magento/module-directory/etc/config.xml

I added to the $_allowedCurrencies array:

'ZZZ', /*Custom Currency*/

vendor/magento/zendframework1/library/Zend/Locale/Data/root.xml

<currency type="ZZZ">
    <symbol alt="narrow">CC</symbol>
</currency>

vendor/magento/zendframework1/library/Zend/Locale/Data/supplementalData.xml

<region iso3166="150"><!-- Europe -->
    <currency iso4217="EUR" from="1999-01-01"/>
    <currency iso4217="ZZZ" from="2011-04-01"/>
</region>

And in the same file I added to the section

<info iso4217="ZZZ" digits="2" rounding="0"/>

I refreshed and flushed all caches and the cache container several times and deleted all files in var/cache manually, but the new currency will not appear in the "Allowed Currencies" or the other dropdowns.

Can someone please help me with this?

  • 1
    Please add your code in the question, showing what all you have tried. – Sourabh Kumar Sharma Aug 8 '18 at 10:04
0

The 'Allowed Currencies' multiselect is defined in htdocs/vendor/magento/module-directory/etc/adminhtml/system.xml:30:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
    <system>
        <section id="currency" translate="label" sortOrder="60" showInDefault="1" showInWebsite="1" showInStore="1">
            <label>Currency Setup</label>
            <tab>general</tab>
            <resource>Magento_Config::currency</resource>
            <group id="options" translate="label" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
                <label>Currency Options</label>
                <field id="allow" translate="label" type="multiselect" sortOrder="3" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
                    <label>Allowed Currencies</label>
                    <source_model>Magento\Config\Model\Config\Source\Locale\Currency</source_model>
                    <backend_model>Magento\Config\Model\Config\Backend\Currency\Allow</backend_model>
                    <can_be_empty>1</can_be_empty>
                </field>

                ...

As you can see, there are two models which control the field.

\Magento\Config\Model\Config\Source\Locale\Currency is used to actually populate the field.

If you dig deep enough, you'll find the list of allowed currencies is actually defined in \Magento\Framework\Locale\Config::$_allowedCurrencies.

So, the first step to adding your currency is to inject your currency code into that classes' constructor. As you can see in the constructor, the injected arguments are merged with the pre-defined array of currency codes:

    /**
     * @param array $data
     */
    public function __construct(array $data = [])
    {
        ...

        if (isset($data['allowedCurrencies']) && is_array($data['allowedCurrencies'])) {
            $this->_allowedCurrencies = array_merge($this->_allowedCurrencies, $data['allowedCurrencies']);
        }
    }

So that gets your currency code to appear in the 'Allowed Currencies' multiselect.

That's only half the story though - we still need to save it.

Referring back to the config XML file, \Magento\Config\Model\Config\Backend\Currency\Allow is used to validate and save the field.

In this class, Magento 2 will validate that the currency selected is defined in a list of installed currencies, which is defined in htdocs/vendor/magento/module-directory/etc/config.xml:12

So you'll need to create a config XML file in your custom currency module and add your custom currency code to that too.

0

May be not the best but quick solution for M2.2.5 with one StoreView: Create new module or use an existing one, e.g. VendorName/ModuleName.

Create a model, for example: app/code/VendorName/ModuleName/Model/Config/AddCurrencies.php

<?php
namespace VendorName\ModuleName\Model\Config;
use Magento\Framework\Locale\Bundle\CurrencyBundle;

class AddCurrencies extends \Magento\Framework\Locale\TranslatedLists
{

    public function getNewCurrencies() 
    {
        /* 
           This is your function that returns an array with new
           currencies. For example: 
         */
        return [
            ['value' => 'LTC', 'label' => 'Litecoin'],
            ['value' => 'BTC', 'label' => 'Bitcoin'],
            ['value' => 'ETH', 'label' => 'Etherium'],
        ];
    }

    public function getOptionAllCurrencies()
    {
        $currencyBundle = new \Magento\Framework\Locale\Bundle\CurrencyBundle();
        $locale = $this->localeResolver->getLocale();
        $currencies = $currencyBundle->get($locale)['Currencies'] ?: [];

        $options = [];
        foreach ($currencies as $code => $data) {
            $options[] = ['label' => $data[1], 'value' => $code];
        }
        $options = array_merge($options, $this->getNewCurrencies());

        return $this->_sortOptionArray($options);
    }

    public function getOptionCurrencies()
    {
        $currencies = (new CurrencyBundle())->get($this->localeResolver->getLocale())['Currencies'] ?: [];
        $options = [];
        $allowed = $this->_config->getAllowedCurrencies();
        foreach ($currencies as $code => $data) {
            if (!in_array($code, $allowed)) {
                continue;
            }
            $options[] = ['label' => $data[1], 'value' => $code];
        }
        $options = array_merge($options, $this->getNewCurrencies());

        return $this->_sortOptionArray($options);
    }


}

add preference to di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
........
    <preference for="Magento\Framework\Locale\TranslatedLists" type="VendorName\ModuleName\Model\Config\AddCurrencies" />
........
</config>

Then clear cache and remove /generated/code and /generated/metadata.

Proceed to Store -> Configuration -> Advanced -> System -> Currency, select and save newly installed currencies. Then go to Store -> Configuration -> General -> Currency Setup and add new currencies to Allowed currencies list.

Now you can add the symbols to your currencies (Stores->Currency Symbol) and install an appropriate provider to retrieve currency rates.

That's all.

Better ideas are welcome!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.