From 6ed8ea117af1dc6145695ed94f591c732b8ff386 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Thu, 17 Jan 2019 00:04:57 -0700 Subject: [PATCH] Refactor formatCurrency() to use store settings for formatting rather than store locale. --- .../client/analytics/report/orders/table.js | 4 +- .../header/activity-panel/panels/orders.js | 6 +-- .../packages/currency/README.md | 7 ++-- .../packages/currency/src/index.js | 41 +++++++++++-------- .../packages/currency/test/index.js | 34 ++++++--------- .../tests/js/setup-globals.js | 2 +- 6 files changed, 45 insertions(+), 49 deletions(-) diff --git a/plugins/woocommerce-admin/client/analytics/report/orders/table.js b/plugins/woocommerce-admin/client/analytics/report/orders/table.js index 96082cebd3d..4c2c08a4083 100644 --- a/plugins/woocommerce-admin/client/analytics/report/orders/table.js +++ b/plugins/woocommerce-admin/client/analytics/report/orders/table.js @@ -105,7 +105,7 @@ class OrdersReportTable extends Component { line_items, items_sold, coupon_lines, - currency, + currency_symbol, net_revenue, } = row; @@ -167,7 +167,7 @@ class OrdersReportTable extends Component { value: coupons.map( item => item.code ).join( ' ' ), }, { - display: formatCurrency( net_revenue, currency ), + display: formatCurrency( net_revenue, currency_symbol ), value: net_revenue, }, ]; diff --git a/plugins/woocommerce-admin/client/header/activity-panel/panels/orders.js b/plugins/woocommerce-admin/client/header/activity-panel/panels/orders.js index 0ff01fc295b..5dd9d83787b 100644 --- a/plugins/woocommerce-admin/client/header/activity-panel/panels/orders.js +++ b/plugins/woocommerce-admin/client/header/activity-panel/panels/orders.js @@ -133,11 +133,11 @@ function OrdersPanel( { orders, isRequesting, isError } ) { { refundValue ? ( - { formatCurrency( total, order.currency ) }{' '} - { formatCurrency( remainingTotal, order.currency ) } + { formatCurrency( total, order.currency_symbol ) }{' '} + { formatCurrency( remainingTotal, order.currency_symbol ) } ) : ( - { formatCurrency( total, order.currency ) } + { formatCurrency( total, order.currency_symbol ) } ) } } diff --git a/plugins/woocommerce-admin/packages/currency/README.md b/plugins/woocommerce-admin/packages/currency/README.md index 78b755186fc..5236a9d80ec 100644 --- a/plugins/woocommerce-admin/packages/currency/README.md +++ b/plugins/woocommerce-admin/packages/currency/README.md @@ -17,10 +17,9 @@ _This package assumes that your code will run in an **ES2015+** environment. If ```JS import { formatCurrency, getCurrencyFormatDecimal, getCurrencyFormatString } from '@woocommerce/currency'; -// Formats money with a given currency code. Uses site's current locale for symbol formatting, -// from the wcSettings global. Defaults to `en-US`. If no currency provided, this is also -// pulled from wcSettings, and defaults to USD. -const total = formatCurrency( 20.923, 'USD' ); // '$20.92' +// Formats money with a given currency symbol. Uses site's currency settings for formatting, +// from the wcSettings global. Defaults to symbol=`$`, precision=2, decimalSeparator=`.`, thousandSeparator=`,` +const total = formatCurrency( 20.923, '$' ); // '$20.92' // Get the rounded decimal value of a number at the precision used for the current currency, // from the wcSettings global. Defaults to 2. diff --git a/plugins/woocommerce-admin/packages/currency/src/index.js b/plugins/woocommerce-admin/packages/currency/src/index.js index 3aad8d81877..6c473945f5c 100644 --- a/plugins/woocommerce-admin/packages/currency/src/index.js +++ b/plugins/woocommerce-admin/packages/currency/src/index.js @@ -3,28 +3,35 @@ * External dependencies */ import { get, isNaN } from 'lodash'; +import { sprintf } from '@wordpress/i18n'; /** - * Formats money with a given currency code. Uses site's current locale for symbol formatting - * - * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat - * @param {Number|String} number number to format - * @param {String} currency currency code e.g. 'USD' - * @returns {?String} A formatted string. + * Internal dependencies */ -export function formatCurrency( number, currency ) { - const locale = wcSettings.siteLocale || 'en-US'; // Default so we don't break. - // default to wcSettings if currency is not passed in - if ( ! currency ) { - currency = get( wcSettings, 'currency.code', 'USD' ); +import { numberFormat } from 'lib/number'; + +/** + * Formats money with a given currency code. Uses site's currency settings for formatting. + * + * @param {Number|String} number number to format + * @param {String} currencySymbol currency code e.g. '$' + * @returns {?String} A formatted string. + */ +export function formatCurrency( number, currencySymbol ) { + // default to wcSettings if currency symbol is not passed in + if ( ! currencySymbol ) { + currencySymbol = get( wcSettings, [ 'currency', 'symbol' ], '$' ); } - if ( 'number' !== typeof number ) { - number = parseFloat( number ); + + const precision = get( wcSettings, [ 'currency', 'precision' ], 2 ); + const formattedNumber = numberFormat( number, precision ); + const priceFormat = get( wcSettings, [ 'currency', 'price_format' ], '%1$s%2$s' ); + + if ( '' === formattedNumber ) { + return formattedNumber; } - if ( isNaN( number ) ) { - return ''; - } - return new Intl.NumberFormat( locale, { style: 'currency', currency } ).format( number ); + + return sprintf( priceFormat, currencySymbol, formattedNumber ); } /** diff --git a/plugins/woocommerce-admin/packages/currency/test/index.js b/plugins/woocommerce-admin/packages/currency/test/index.js index c3f978bb14d..95ca86ef52c 100644 --- a/plugins/woocommerce-admin/packages/currency/test/index.js +++ b/plugins/woocommerce-admin/packages/currency/test/index.js @@ -10,32 +10,22 @@ describe( 'formatCurrency', () => { expect( formatCurrency( 30 ) ).toBe( '$30.00' ); } ); - it( 'should round a number to 2 decimal places in USD', () => { - expect( formatCurrency( 9.49258, 'USD' ) ).toBe( '$9.49' ); - expect( formatCurrency( 30, 'USD' ) ).toBe( '$30.00' ); - expect( formatCurrency( 3.0002, 'USD' ) ).toBe( '$3.00' ); - } ); + it( 'should uses store currency settings, not locale-based', () => { + global.wcSettings.currency.code = 'JPY'; + global.wcSettings.currency.precision = 3; + global.wcSettings.currency.decimal_separator = ','; + global.wcSettings.currency.thousand_separator = '.'; + global.wcSettings.currency.price_format = '%2$s%1$s'; - it( 'should round a number to 2 decimal places in GBP', () => { - expect( formatCurrency( 8.9272, 'GBP' ) ).toBe( '£8.93' ); - expect( formatCurrency( 11, 'GBP' ) ).toBe( '£11.00' ); - expect( formatCurrency( 7.0002, 'GBP' ) ).toBe( '£7.00' ); - } ); - - it( 'should round a number to 0 decimal places in JPY', () => { - expect( formatCurrency( 1239.88, 'JPY' ) ).toBe( '¥1,240' ); - expect( formatCurrency( 1500, 'JPY' ) ).toBe( '¥1,500' ); - expect( formatCurrency( 33715.02, 'JPY' ) ).toBe( '¥33,715' ); - } ); - - it( 'should correctly convert and round a string', () => { - expect( formatCurrency( '19.80', 'USD' ) ).toBe( '$19.80' ); + expect( formatCurrency( 9.49258, '¥' ) ).toBe( '9,493¥' ); + expect( formatCurrency( 3000, '¥' ) ).toBe( '3.000,000¥' ); + expect( formatCurrency( 3.0002, '¥' ) ).toBe( '3,000¥' ); } ); it( "should return empty string when given an input that isn't a number", () => { - expect( formatCurrency( 'abc', 'USD' ) ).toBe( '' ); - expect( formatCurrency( false, 'USD' ) ).toBe( '' ); - expect( formatCurrency( null, 'USD' ) ).toBe( '' ); + expect( formatCurrency( 'abc' ) ).toBe( '' ); + expect( formatCurrency( false ) ).toBe( '' ); + expect( formatCurrency( null ) ).toBe( '' ); } ); } ); diff --git a/plugins/woocommerce-admin/tests/js/setup-globals.js b/plugins/woocommerce-admin/tests/js/setup-globals.js index 6c0d6f9ad78..e07b32c27ab 100644 --- a/plugins/woocommerce-admin/tests/js/setup-globals.js +++ b/plugins/woocommerce-admin/tests/js/setup-globals.js @@ -44,7 +44,7 @@ wooCommercePackages.forEach( lib => { global.wcSettings = { adminUrl: 'https://vagrant.local/wp/wp-admin/', locale: 'en-US', - currency: { code: 'USD', precision: 2, symbol: '$' }, + currency: { code: 'USD', precision: 2, symbol: '$' }, date: { dow: 0, },