5

Currently I successfully override the Price display base on local currency on other pages. But I got a problem on Product Details page. The price is override by price-utils.js file:

Magento/Catalog/view/base/web/js/price-utils.js

on formatPrice() method on line number 73.

(precision ? decimalSymbol + am.toFixed(2).replace(/-/, 0).slice(2) : '');

I tried to override the method via mixins.

requirejs-config.js

var config = {
    'config': {
        'mixins': {
            'Magento_Catalog/js/price-utils': {
                'MyModule_PriceDecimal/js/price-utils-mixin': true
            }
        }
    }
};

price-utils-mixin.js

define([
    'jquery',
    'underscore'
], function ($, _) {
    'use strict';

    var globalPriceFormat = {
        requiredPrecision: 2,
        integerRequired: 1,
        decimalSymbol: ',',
        groupSymbol: ',',
        groupLength: ','
    };

    return {
        formatPrice: formatPrice
    };

    /**
     * Formatter for price amount
     * @param  {Number}  amount
     * @param  {Object}  format
     * @param  {Boolean} isShowSign
     * @return {String}              Formatted value
     */
    function formatPrice(amount, format, isShowSign) {
        format = _.extend(globalPriceFormat, format);

        // copied from price-option.js | Could be refactored with varien/js.js

        var precision = isNaN(format.requiredPrecision = Math.abs(format.requiredPrecision)) ? 2 : format.requiredPrecision,
            integerRequired = isNaN(format.integerRequired = Math.abs(format.integerRequired)) ? 1 : format.integerRequired,
            decimalSymbol = format.decimalSymbol === undefined ? ',' : format.decimalSymbol,
            groupSymbol = format.groupSymbol === undefined ? '.' : format.groupSymbol,
            groupLength = format.groupLength === undefined ? 3 : format.groupLength,
            pattern = format.pattern || '%s',
            s = '',
            i, pad,
            j, re, r, am;

        if (isShowSign === undefined || isShowSign === true) {
            s = amount < 0 ? '-' : (isShowSign ? '+' : '');
        } else if (isShowSign === false) {
            s = '';
        }
        pattern = pattern.indexOf('{sign}') < 0 ? s + pattern : pattern.replace('{sign}', s);

        // we're avoiding the usage of to fixed, and using round instead with the e representation to address
        // numbers like 1.005 = 1.01. Using ToFixed to only provide trailig zeroes in case we have a whole number
        i = parseInt(amount = Number(Math.round(Math.abs(+amount || 0) + 'e+' + precision) + ('e-' + precision)) , 10) + '';
        pad = (i.length < integerRequired) ? (integerRequired - i.length) : 0;

        i = stringPad('0', pad) + i;

        j = i.length > groupLength ? i.length % groupLength : 0;
        re = new RegExp('(\\d{' + groupLength + '})(?=\\d)', 'g');

        // replace(/-/, 0) is only for fixing Safari bug which appears
        // when Math.abs(0).toFixed() executed on '0' number.
        // Result is '0.-0' :(

        am = Number(Math.round(Math.abs(amount - i) + 'e+' + precision) + ('e-' + precision));
        r = (j ? i.substr(0, j) + groupSymbol : '') +
            i.substr(j).replace(re, '$1' + groupSymbol) +
            (precision ? decimalSymbol + am.toFixed(precision).replace(/-/, 0).slice(2) : '');

        return pattern.replace('%s', r).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
    }
});

You will noticed that I have change from

(precision ? decimalSymbol + am.toFixed(2).replace(/-/, 0).slice(2) : '');

To

(precision ? decimalSymbol + am.toFixed(precision).replace(/-/, 0).slice(2) : '');

The script is working but I have a console error:

fd70f83ecce9b7063bc426e38ccbea7f.js:2154 Uncaught TypeError: mixin is not a function
    at fd70f83ecce9b7063bc426e38ccbea7f.js:2154
    at Array.forEach (<anonymous>)
    at applyMixins (fd70f83ecce9b7063bc426e38ccbea7f.js:2153)
    at fd70f83ecce9b7063bc426e38ccbea7f.js:2173
    at Object.execCb (fd70f83ecce9b7063bc426e38ccbea7f.js:1650)
    at Module.check (fd70f83ecce9b7063bc426e38ccbea7f.js:866)
    at Module.<anonymous> (fd70f83ecce9b7063bc426e38ccbea7f.js:1113)
    at fd70f83ecce9b7063bc426e38ccbea7f.js:132
    at fd70f83ecce9b7063bc426e38ccbea7f.js:1156
    at each (fd70f83ecce9b7063bc426e38ccbea7f.js:57)

That's the problem I have currently, I wanted to know how/what would be the best way to override this method without having any error on mixins js console toolbar.

Any suggestions/help is always appreciated. Thanks!

2 Answers 2

4

Using mixins is to follow the best practice. But in your script, should try:

define([
    'jquery',
    'underscore'
   ],
    function ($, _) {
        'use strict';
        return function (target) {

            target.formatPrice = function formatPrice(amount, format, isShowSign) {
                //Your custom format price here
            };

            return target;
    };
});

[EDIT] Add others dependencies if we want.

4
  • 1
    Thanks @khoa, it works I just added some others dependencies to make it work. The thing is that the way you have provide is absolutely correct. Commented Dec 14, 2017 at 9:38
  • where this script add ??? Commented Nov 9, 2019 at 5:32
  • @kho, globalPriceFormat is not defined. Commented Jul 10, 2020 at 6:06
  • @kho, ReferenceError: stringPad is not defined. Commented Jul 10, 2020 at 7:01
0

You can try this:

define([
    'jquery',
    'underscore'
   ],
    function ($, _) {
        'use strict';
        return function (target) {

            target.formatPrice = function formatPrice(amount, format, isShowSign) {
                //Your custom format price here
                /*
                 if you call another function from this function then you 
                 should use "target.<return a function's of Key-name>"
                */
            };

            return target;
    };
});

Because of parent price-util.js return.

return {
        formatPrice: formatPrice,
        deepClone: objectDeepClone,
        strPad: stringPad,
        findOptionId: findOptionId
    };

Thanks,

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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