Skip to content

Commit 104f40c

Browse files
Merge pull request woocommerce#24281 from woocommerce/fix/24269
Handle multiple decimal points
2 parents d20d429 + 8563577 commit 104f40c

File tree

5 files changed

+45
-12
lines changed

5 files changed

+45
-12
lines changed

assets/js/admin/woocommerce_admin.js

+18-6
Original file line numberDiff line numberDiff line change
@@ -61,39 +61,51 @@
6161
})
6262

6363
.on( 'change', '.wc_input_price[type=text], .wc_input_decimal[type=text], .wc-order-totals #refund_amount[type=text]', function() {
64-
var regex;
64+
var regex, decimalRegex,
65+
decimailPoint = woocommerce_admin.decimal_point;
6566

6667
if ( $( this ).is( '.wc_input_price' ) || $( this ).is( '#refund_amount' ) ) {
67-
regex = new RegExp( '[^\-0-9\%\\' + woocommerce_admin.mon_decimal_point + ']+', 'gi' );
68-
} else {
69-
regex = new RegExp( '[^\-0-9\%\\' + woocommerce_admin.decimal_point + ']+', 'gi' );
68+
decimailPoint = woocommerce_admin.mon_decimal_point;
7069
}
7170

71+
regex = new RegExp( '[^\-0-9\%\\' + decimailPoint + ']+', 'gi' );
72+
decimalRegex = new RegExp( '\\' + decimailPoint + '+', 'gi' );
73+
7274
var value = $( this ).val();
73-
var newvalue = value.replace( regex, '' );
75+
var newvalue = value.replace( regex, '' ).replace( decimalRegex, decimailPoint );
7476

7577
if ( value !== newvalue ) {
7678
$( this ).val( newvalue );
7779
}
7880
})
7981

8082
.on( 'keyup', '.wc_input_price[type=text], .wc_input_decimal[type=text], .wc_input_country_iso[type=text], .wc-order-totals #refund_amount[type=text]', function() {
81-
var regex, error;
83+
var regex, error, decimalRegex;
84+
var checkDecimalNumbers = false;
8285

8386
if ( $( this ).is( '.wc_input_price' ) || $( this ).is( '#refund_amount' ) ) {
87+
checkDecimalNumbers = true;
8488
regex = new RegExp( '[^\-0-9\%\\' + woocommerce_admin.mon_decimal_point + ']+', 'gi' );
89+
decimalRegex = new RegExp( '[^\\' + woocommerce_admin.mon_decimal_point + ']', 'gi' );
8590
error = 'i18n_mon_decimal_error';
8691
} else if ( $( this ).is( '.wc_input_country_iso' ) ) {
8792
regex = new RegExp( '([^A-Z])+|(.){3,}', 'im' );
8893
error = 'i18n_country_iso_error';
8994
} else {
95+
checkDecimalNumbers = true;
9096
regex = new RegExp( '[^\-0-9\%\\' + woocommerce_admin.decimal_point + ']+', 'gi' );
97+
decimalRegex = new RegExp( '[^\\' + woocommerce_admin.decimal_point + ']', 'gi' );
9198
error = 'i18n_decimal_error';
9299
}
93100

94101
var value = $( this ).val();
95102
var newvalue = value.replace( regex, '' );
96103

104+
// Check if newvalue have more than one decimal point.
105+
if ( checkDecimalNumbers && 1 < newvalue.replace( decimalRegex, '' ).length ) {
106+
newvalue = newvalue.replace( decimalRegex, '' );
107+
}
108+
97109
if ( value !== newvalue ) {
98110
$( document.body ).triggerHandler( 'wc_add_error_tip', [ $( this ), error ] );
99111
} else {

includes/admin/class-wc-admin-assets.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -169,9 +169,9 @@ public function admin_scripts() {
169169

170170
$params = array(
171171
/* translators: %s: decimal */
172-
'i18n_decimal_error' => sprintf( __( 'Please enter in decimal (%s) format without thousand separators.', 'woocommerce' ), $decimal ),
172+
'i18n_decimal_error' => sprintf( __( 'Please enter with one decimal point (%s) without thousand separators.', 'woocommerce' ), $decimal ),
173173
/* translators: %s: price decimal separator */
174-
'i18n_mon_decimal_error' => sprintf( __( 'Please enter in monetary decimal (%s) format without thousand separators and currency symbols.', 'woocommerce' ), wc_get_price_decimal_separator() ),
174+
'i18n_mon_decimal_error' => sprintf( __( 'Please enter with one monetary decimal point (%s) without thousand separators and currency symbols.', 'woocommerce' ), wc_get_price_decimal_separator() ),
175175
'i18n_country_iso_error' => __( 'Please enter in country code with two capital letters.', 'woocommerce' ),
176176
'i18n_sale_less_than_regular_error' => __( 'Please enter in a value less than the regular price.', 'woocommerce' ),
177177
'i18n_delete_product_notice' => __( 'This product has produced sales and may be linked to existing orders. Are you sure you want to delete it?', 'woocommerce' ),

includes/data-stores/class-wc-product-variable-data-store-cpt.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ public function read_price_data( &$product, $for_display = false ) {
361361

362362
$prices_array['price'][ $variation_id ] = wc_format_decimal( $price, wc_get_price_decimals() );
363363
$prices_array['regular_price'][ $variation_id ] = wc_format_decimal( $regular_price, wc_get_price_decimals() );
364-
$prices_array['sale_price'][ $variation_id ] = wc_format_decimal( $sale_price . '.00', wc_get_price_decimals() );
364+
$prices_array['sale_price'][ $variation_id ] = wc_format_decimal( $sale_price, wc_get_price_decimals() );
365365

366366
$prices_array = apply_filters( 'woocommerce_variation_prices_array', $prices_array, $variation, $for_display );
367367
}

includes/wc-formatting-functions.php

+5-2
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,9 @@ function wc_format_decimal( $number, $dp = false, $trim_zeros = false ) {
292292
// Remove locale from string.
293293
if ( ! is_float( $number ) ) {
294294
$number = str_replace( $decimals, '.', $number );
295-
$number = preg_replace( '/[^0-9\.,-]/', '', wc_clean( $number ) );
295+
296+
// Convert multiple dots to just one.
297+
$number = preg_replace( '/\.(?![^.]+$)|[^0-9.-]/', '', wc_clean( $number ) );
296298
}
297299

298300
if ( false !== $dp ) {
@@ -735,7 +737,8 @@ function wc_timezone_string() {
735737
// Last try, guess timezone string manually.
736738
foreach ( timezone_abbreviations_list() as $abbr ) {
737739
foreach ( $abbr as $city ) {
738-
if ( (bool) date( 'I' ) === (bool) $city['dst'] && $city['timezone_id'] && intval( $city['offset'] ) === $utc_offset ) {
740+
// WordPress restrict the use of date(), since it's affected by timezone settings, but in this case is just what we need to guess the correct timezone.
741+
if ( (bool) date( 'I' ) === (bool) $city['dst'] && $city['timezone_id'] && intval( $city['offset'] ) === $utc_offset ) { // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
739742
return $city['timezone_id'];
740743
}
741744
}

tests/unit-tests/formatting/functions.php

+19-1
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,15 @@ public function test_wc_format_decimal() {
298298
// Given string.
299299
$this->assertEquals( '9.99', wc_format_decimal( '9.99' ) );
300300

301+
// Given string with multiple decimals points.
302+
$this->assertEquals( '9.99', wc_format_decimal( '9...99' ) );
303+
304+
// Given string with multiple decimals points.
305+
$this->assertEquals( '99.9', wc_format_decimal( '9...9....9' ) );
306+
307+
// Negative string.
308+
$this->assertEquals( '-9.99', wc_format_decimal( '-9.99' ) );
309+
301310
// Float.
302311
$this->assertEquals( '9.99', wc_format_decimal( 9.99 ) );
303312

@@ -324,7 +333,16 @@ public function test_wc_format_decimal() {
324333
update_option( 'woocommerce_price_thousand_sep', '.' );
325334

326335
// Given string.
327-
$this->assertEquals( '9.99', wc_format_decimal( '9.99' ) );
336+
$this->assertEquals( '9.99', wc_format_decimal( '9,99' ) );
337+
338+
// Given string with multiple decimals points.
339+
$this->assertEquals( '9.99', wc_format_decimal( '9,,,99' ) );
340+
341+
// Given string with multiple decimals points.
342+
$this->assertEquals( '99.9', wc_format_decimal( '9,,,9,,,,9' ) );
343+
344+
// Negative string.
345+
$this->assertEquals( '-9.99', wc_format_decimal( '-9,99' ) );
328346

329347
// Float.
330348
$this->assertEquals( '9.99', wc_format_decimal( 9.99 ) );

0 commit comments

Comments
 (0)