Wie ändere ich das Währungsformat in Magento 2?

8

Derzeit zeigt der Preis wie $ 2.999,00

Ich möchte den Preis wie 2.999,00 $ zu zeigen , für locale es_MX (spanisch, Mexiko) in den Produktseiten , anderswo das Währungsformat korrekt ist.

Ich habe alle Lösungen in Stackexchange ausprobiert, aber niemand funktioniert.

Datei app / code / Jsp / Currency / etc / di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Framework\Locale\Format" type="Jsp\Currency\Model\Format"/>
</config>

Datei app / code / Jsp / Currency / Model / Format.php

<?php
namespace Jsp\Currency\Model;

use Magento\Framework\Locale\Bundle\DataBundle;

class Format extends \Magento\Framework\Locale\Format
{
    private static $defaultNumberSet = 'latn';

    public function getPriceFormat($localeCode = null, $currencyCode = null)
    {
        $localeCode = $localeCode ?: $this->_localeResolver->getLocale();
        if ($currencyCode) {
            $currency = $this->currencyFactory->create()->load($currencyCode);
        } else {
            $currency = $this->_scopeResolver->getScope()->getCurrentCurrency();
        }

        $localeData = (new DataBundle())->get($localeCode);
        $defaultSet = $localeData['NumberElements']['default'] ?: self::$defaultNumberSet;

        $format = $localeData['NumberElements'][$defaultSet]['patterns']['currencyFormat']
            ?: ($localeData['NumberElements'][self::$defaultNumberSet]['patterns']['currencyFormat']
                ?: explode(';', $localeData['NumberPatterns'][1])[0]);

        //your main changes are gone here.....
        if($localeCode == 'es_MX'){
            $decimalSymbol = '.';
            $groupSymbol = ',';
        }else{
            $decimalSymbol = $localeData['NumberElements'][$defaultSet]['symbols']['decimal']
                ?: ($localeData['NumberElements'][self::$defaultNumberSet]['symbols']['decimal']
                    ?: $localeData['NumberElements'][0]);

            $groupSymbol = $localeData['NumberElements'][$defaultSet]['symbols']['group']
                ?: ($localeData['NumberElements'][self::$defaultNumberSet]['symbols']['group']
                    ?: $localeData['NumberElements'][1]);
        }

        $pos = strpos($format, ';');
        if ($pos !== false) {
            $format = substr($format, 0, $pos);
        }
        $format = preg_replace("/[^0\#\.,]/", "", $format);
        $totalPrecision = 0;
        $decimalPoint = strpos($format, '.');
        if ($decimalPoint !== false) {
            $totalPrecision = strlen($format) - (strrpos($format, '.') + 1);
        } else {
            $decimalPoint = strlen($format);
        }
        $requiredPrecision = $totalPrecision;
        $t = substr($format, $decimalPoint);
        $pos = strpos($t, '#');
        if ($pos !== false) {
            $requiredPrecision = strlen($t) - $pos - $totalPrecision;
        }

        if (strrpos($format, ',') !== false) {
            $group = $decimalPoint - strrpos($format, ',') - 1;
        } else {
            $group = strrpos($format, '.');
        }
        $integerRequired = strpos($format, '.') - strpos($format, '0');

        $result = [
            //TODO: change interface
            'pattern' => $currency->getOutputFormat(),
            'precision' => $totalPrecision,
            'requiredPrecision' => $requiredPrecision,
            'decimalSymbol' => $decimalSymbol,
            'groupSymbol' => $groupSymbol,
            'groupLength' => $group,
            'integerRequired' => $integerRequired,
        ];       
        return $result;
    }
}

Dateianbieter / magento / framework / Locale / Format.php

<?php
/**
 * Copyright © 2016 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Magento\Framework\Locale;

use Magento\Framework\Locale\Bundle\DataBundle;

class Format implements \Magento\Framework\Locale\FormatInterface
{
    /**
     * @var string
     */
    private static $defaultNumberSet = 'latn';

    /**
     * @var \Magento\Framework\App\ScopeResolverInterface
     */
    protected $_scopeResolver;

    /**
     * @var \Magento\Framework\Locale\ResolverInterface
     */
    protected $_localeResolver;

    /**
     * @var \Magento\Directory\Model\CurrencyFactory
     */
    protected $currencyFactory;

    /**
     * @param \Magento\Framework\App\ScopeResolverInterface $scopeResolver
     * @param ResolverInterface $localeResolver
     * @param \Magento\Directory\Model\CurrencyFactory $currencyFactory
     */
    public function __construct(
        \Magento\Framework\App\ScopeResolverInterface $scopeResolver,
        \Magento\Framework\Locale\ResolverInterface $localeResolver,
        \Magento\Directory\Model\CurrencyFactory $currencyFactory
    ) {
        $this->_scopeResolver = $scopeResolver;
        $this->_localeResolver = $localeResolver;
        $this->currencyFactory = $currencyFactory;
    }

    /**
     * Returns the first found number from an string
     * Parsing depends on given locale (grouping and decimal)
     *
     * Examples for input:
     * '  2345.4356,1234' = 23455456.1234
     * '+23,3452.123' = 233452.123
     * ' 12343 ' = 12343
     * '-9456km' = -9456
     * '0' = 0
     * '2 054,10' = 2054.1
     * '2'054.52' = 2054.52
     * '2,46 GB' = 2.46
     *
     * @param string|float|int $value
     * @return float|null
     */
    public function getNumber($value)
    {
        if ($value === null) {
            return null;
        }

        if (!is_string($value)) {
            return floatval($value);
        }

        //trim spaces and apostrophes
        $value = str_replace(['\'', ' '], '', $value);

        $separatorComa = strpos($value, ',');
        $separatorDot = strpos($value, '.');

        if ($separatorComa !== false && $separatorDot !== false) {
            if ($separatorComa > $separatorDot) {
                $value = str_replace('.', '', $value);
                $value = str_replace(',', '.', $value);
            } else {
                $value = str_replace(',', '', $value);
            }
        } elseif ($separatorComa !== false) {
            $value = str_replace(',', '.', $value);
        }

        return floatval($value);
    }

    /**
     * Functions returns array with price formatting info
     *
     * @param string $localeCode Locale code.
     * @param string $currencyCode Currency code.
     * @return array
     * @SuppressWarnings(PHPMD.NPathComplexity)
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     */
    public function getPriceFormat($localeCode = null, $currencyCode = null)
    {
        $localeCode = $localeCode ?: $this->_localeResolver->getLocale();
        if ($currencyCode) {
            $currency = $this->currencyFactory->create()->load($currencyCode);
        } else {
            $currency = $this->_scopeResolver->getScope()->getCurrentCurrency();
        }
        $localeData = (new DataBundle())->get($localeCode);
        $defaultSet = $localeData['NumberElements']['default'] ?: self::$defaultNumberSet;
        $format = $localeData['NumberElements'][$defaultSet]['patterns']['currencyFormat']
            ?: ($localeData['NumberElements'][self::$defaultNumberSet]['patterns']['currencyFormat']
                ?: explode(';', $localeData['NumberPatterns'][1])[0]);

        $decimalSymbol = $localeData['NumberElements'][$defaultSet]['symbols']['decimal']
            ?: ($localeData['NumberElements'][self::$defaultNumberSet]['symbols']['decimal']
                ?: $localeData['NumberElements'][0]);

        $groupSymbol = $localeData['NumberElements'][$defaultSet]['symbols']['group']
            ?: ($localeData['NumberElements'][self::$defaultNumberSet]['symbols']['group']
                ?: $localeData['NumberElements'][1]);

        $pos = strpos($format, ';');
        if ($pos !== false) {
            $format = substr($format, 0, $pos);
        }
        $format = preg_replace("/[^0\#\.,]/", "", $format);
        $totalPrecision = 0;
        $decimalPoint = strpos($format, '.');
        if ($decimalPoint !== false) {
            $totalPrecision = strlen($format) - (strrpos($format, '.') + 1);
        } else {
            $decimalPoint = strlen($format);
        }
        $requiredPrecision = $totalPrecision;
        $t = substr($format, $decimalPoint);
        $pos = strpos($t, '#');
        if ($pos !== false) {
            $requiredPrecision = strlen($t) - $pos - $totalPrecision;
        }

        if (strrpos($format, ',') !== false) {
            $group = $decimalPoint - strrpos($format, ',') - 1;
        } else {
            $group = strrpos($format, '.');
        }
        $integerRequired = strpos($format, '.') - strpos($format, '0');

        $result = [
            //TODO: change interface
            'pattern' => $currency->getOutputFormat(),
            'precision' => $totalPrecision,
            'requiredPrecision' => $requiredPrecision,
            'decimalSymbol' => $decimalSymbol,
            'groupSymbol' => $groupSymbol,
            'groupLength' => $group,
            'integerRequired' => $integerRequired,
        ];

        return $result;
    }
}
Luis Garcia
quelle
Bitte überprüfen Sie die aktualisierte Antwort und lassen Sie mich wissen, wenn Sie ein Problem haben. Dies ist der Arbeitscode für Ihr Problem. Ich habe das gleiche Problem für die spanische Seite und habe es mit dem folgenden Code gelöst. Vielen Dank.
Rakesh Jesadiya
Entfernen Sie die Bedingungen in Ihrem Code und behalten Sie einfach $ decimalSymbol = '.' Und $ groupSymbol = ',' entferne var und überprüfe. Für weitere Informationen habe ich den Code aktualisiert. Überprüfen Sie bitte das.
Rakesh Jesadiya
Bitte überprüfen Sie, ob Ihre benutzerdefinierte Modulfunktion aufgerufen wird oder nicht. Sie können die obige Funktion debuggen, ob Ihr Code in der Funktion getPriceFormat enthalten ist oder nicht. Der Ursachencode funktioniert bei mir für dieselbe Art von Problem, mit dem ich konfrontiert bin.
Rakesh Jesadiya
Ich habe festgestellt, dass die von Ihnen bereitgestellte Datei Format.php etwas anders ist als die von Ihnen bereitgestellte. Kann das das Problem sein? Können Sie im Hinblick auf das Debuggen der Funktion genauer erläutern, wie ich sie debuggen kann?
Luis Garcia
Muss ich eine Datei register.php in meinem Modulordner hinzufügen?
Luis Garcia

Antworten:

15

Erstelle nur ein einfaches Modul und überschreibe die Standarddatei * Format.php **.

app / code / Package / Modulename / etc / 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\Format" type="Vendor\Currency\Model\Format" />
</config>

Modelldatei erstellen, app / code / Package / Modulename / Model / Format.php

<?php
namespace Package\Modulename\Model;

use Magento\Framework\Locale\Bundle\DataBundle;

class Format extends \Magento\Framework\Locale\Format
{
    private static $defaultNumberSet = 'latn';

    public function getPriceFormat($localeCode = null, $currencyCode = null)
    {
        $localeCode = $localeCode ?: $this->_localeResolver->getLocale();
        if ($currencyCode) {
            $currency = $this->currencyFactory->create()->load($currencyCode);
        } else {
            $currency = $this->_scopeResolver->getScope()->getCurrentCurrency();
        }

        $localeData = (new DataBundle())->get($localeCode);
        $defaultSet = $localeData['NumberElements']['default'] ?: self::$defaultNumberSet;

        $format = $localeData['NumberElements'][$defaultSet]['patterns']['currencyFormat']
            ?: ($localeData['NumberElements'][self::$defaultNumberSet]['patterns']['currencyFormat']
                ?: explode(';', $localeData['NumberPatterns'][1])[0]);

        //your main changes are gone here.....
        $decimalSymbol = '.';
        $groupSymbol = ',';

        $pos = strpos($format, ';');
        if ($pos !== false) {
            $format = substr($format, 0, $pos);
        }
        $format = preg_replace("/[^0\#\.,]/", "", $format);
        $totalPrecision = 0;
        $decimalPoint = strpos($format, '.');
        if ($decimalPoint !== false) {
            $totalPrecision = strlen($format) - (strrpos($format, '.') + 1);
        } else {
            $decimalPoint = strlen($format);
        }
        $requiredPrecision = $totalPrecision;
        $t = substr($format, $decimalPoint);
        $pos = strpos($t, '#');
        if ($pos !== false) {
            $requiredPrecision = strlen($t) - $pos - $totalPrecision;
        }

        if (strrpos($format, ',') !== false) {
            $group = $decimalPoint - strrpos($format, ',') - 1;
        } else {
            $group = strrpos($format, '.');
        }
        $integerRequired = strpos($format, '.') - strpos($format, '0');

        $result = [
            //TODO: change interface
            'pattern' => $currency->getOutputFormat(),
            'precision' => $totalPrecision,
            'requiredPrecision' => $requiredPrecision,
            'decimalSymbol' => $decimalSymbol,
            'groupSymbol' => $groupSymbol,
            'groupLength' => $group,
            'integerRequired' => $integerRequired,
        ];       
        return $result;
    }
}

Vielen Dank.

Rakesh Jesadiya
quelle
Ich habe Ihre Lösung ausprobiert, aber nicht funktioniert. Ich habe meine Antwort mit dem von mir erstellten di.xml-Code aktualisiert. Ich habe auch die Modelldatei erstellt, die den Paket- und Modulnamen so ändert, dass sie mit meinen Ordnernamen übereinstimmt
Luis Garcia
Ich habe meine Frage mit dem Code Format.php aktualisiert. Vielen Dank
Luis Garcia
Ich habe es oben versucht, es funktioniert für die Produktseite, aber nicht für die Kategorieseite, wundere mich !!!
Zinat
Es funktioniert für die gesamte Site. Bitte überprüfen Sie, ob Sie ein Problem haben.
Rakesh Jesadiya
@ RakeshJesadiya, es funktioniert nur für Produktdetailseite und andere Preise wie Summen, Warenkorb usw., aber es funktioniert nicht auf Listingseite,
Minikorb
3

Verwenden Sie den folgenden Code:

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$objectManager->create('\Magento\Framework\Pricing\PriceCurrencyInterface')->format('999,00',true,0);

Formatieren Sie die Funktion wie folgt:

public function format(
        $amount,
        $includeContainer = true,
        $precision = self::DEFAULT_PRECISION,
        $scope = null,
        $currency = null
    );

Wenn $ includeContainer = true ist, wird der Preis mit dem Span-Container angezeigt

<span class="price">$999</span>

$precision = self::DEFAULT_PRECISIONEs werden zwei Dezimalstellen angezeigt. Bei Verwendung von 0 wird kein Dezimalpunkt angezeigt.

Prashant Valanda
quelle
In welche Datei soll ich diesen Code einfügen? Ich bin neu in Magento
Luis Garcia
In welche Datei soll ich diesen Code einfügen?
Luis Garcia
3

Standardmäßig ist das Preisformat von Magento 2 für einige Währungen etwas seltsam, daher müssen wir es ändern. Hier erfahren Sie, wie Sie das Preisformat ändern können.

Hier ist das Beispiel für den Fall des vietnamesischen Dong. Das standardmäßig angezeigte Format war 100.000,00. Dann habe ich es in 100.000 geändert (durch Komma ohne Dezimalpunkt getrennt).

# vendor/magento/zendframework1/library/Zend/Locale/Data/vi.xml
<symbols numbersystem="latn">
 <decimal>.</decimal>
 <group>,</group>
</symbols>

# vendor/magento/framework/Pricing/PriceCurrencyInterface.php
const DEFAULT_PRECISION = 0

# vendor/magento/module-directory/Model/Currency.php
return $this->formatPrecision($price, 0, $options, $includeContainer, $addBrackets);

# vendor/magento/module-sales/Model/Order.php
public function formatPrice($price, $addBrackets = false)
{
    return $this->formatPricePrecision($price, 0, $addBrackets);
}

Danke Viel Spaß :)

Aasim Goriya
quelle
habe es versucht, funktioniert aber nicht für es_MX
Luis Garcia
1
  1. Wechseln Sie von Ihrem Stammordner zu Vendor / magento / zendframework1 / library / Zend / Locale / Data / es_MX.xml
  2. Suchen <currencyFormat

Sie können das Format folgendermaßen einstellen:

<currencyFormat type="standard">
    <pattern draft="contributed">¤#,##0.00</pattern>
</currencyFormat>
Ashish Jagnani
quelle
Dieses Format wurde bereits so eingestellt
Luis Garcia
0

Um Dezimalstellen für verschiedene Währungen zu ändern oder zu entfernen, müssen Sie nur das kostenlose Modul Currency Formatter Extension von Mageplaza hier über den Link https://www.mageplaza.com/magento-2-currency-formatter/ installieren    .

Dann können Sie die Dezimalstelle für Ihre Anforderung über das Magento Admin Panel -> Stores-> Configuration-> Mageplaza Extensions konfigurieren. 

Dies funktionierte bei mir in der Installation von Magento 2.3.3. 

Freundliche Grüße

Sotmir Laci
quelle
-1

Ein schlechter Weg, dies zu tun (aber schneller), ist das Hardcodieren des Anbieters / magento / framework / Locale / Format.php

    $result = [
        //TODO: change interface
        'pattern' => $currency->getOutputFormat(),
        'precision' => $totalPrecision,
        'requiredPrecision' => $requiredPrecision,
        //'decimalSymbol' => $decimalSymbol,
        'decimalSymbol' =>'.',
        //'groupSymbol' => $groupSymbol,
        'groupSymbol' => ',',
        'groupLength' => $group,
        'integerRequired' => $integerRequired,
    ];
alex davila
quelle
Wenn es ein schlechter Weg ist, warum dann vorschlagen? Wir sollten niemals den Kern oder den Anbieter ändern.
Danny Nimmo
Vielen Dank. Ich suchte nach einer schnellen, schmutzigen Lösung, da ich eine aussterbende Website reparieren möchte, während ich an einer neuen Version davon arbeite.
Hassan Al-Jeshi