1
0
Fork 0
mirror of https://github.com/archtechx/money.git synced 2025-12-12 03:14:03 +00:00

Fixes #11 - Remove trailing zeros from formatted price (#18)

* Remove trailing zeros from formatted price

* Add setting for how to handle trailing decimal zeros

* Write tests

* Fix code style

* Rewrite function description

* Change test name

* Add empty line at end of file

* rename deleteTrailingDecimalZeros to trimTrailingDecimalZeros

* Fix grammar

* Remove unnecessary parameter declarations

* fix test name

* fix comment grammar

* fix docblock grammar

Co-authored-by: Samuel Štancl <samuel@archte.ch>
This commit is contained in:
David Andersson 2022-05-16 13:12:13 +02:00 committed by GitHub
parent 545610efb0
commit 269274586a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 52 additions and 1 deletions

View file

@ -40,6 +40,9 @@ class Currency implements Arrayable, JsonSerializable
/** How many decimals of the currency's values should get rounded. */ /** How many decimals of the currency's values should get rounded. */
protected int $rounding; protected int $rounding;
/** Should trailing decimal zeros be trimmed. */
protected bool $trimTrailingDecimalZeros;
/** Create a new Currency instance. */ /** Create a new Currency instance. */
public function __construct( public function __construct(
string $code = null, string $code = null,
@ -52,6 +55,7 @@ class Currency implements Arrayable, JsonSerializable
int $rounding = null, int $rounding = null,
string $decimalSeparator = null, string $decimalSeparator = null,
string $thousandsSeparator = null, string $thousandsSeparator = null,
bool $trimTrailingDecimalZeros = null,
) { ) {
$this->code = $code ?? $this->code ?? ''; $this->code = $code ?? $this->code ?? '';
$this->name = $name ?? $this->name ?? ''; $this->name = $name ?? $this->name ?? '';
@ -63,6 +67,7 @@ class Currency implements Arrayable, JsonSerializable
$this->decimalSeparator = $decimalSeparator ?? $this->decimalSeparator ?? '.'; $this->decimalSeparator = $decimalSeparator ?? $this->decimalSeparator ?? '.';
$this->thousandsSeparator = $thousandsSeparator ?? $this->thousandsSeparator ?? ','; $this->thousandsSeparator = $thousandsSeparator ?? $this->thousandsSeparator ?? ',';
$this->rounding = $rounding ?? $this->rounding ?? $this->mathDecimals; $this->rounding = $rounding ?? $this->rounding ?? $this->mathDecimals;
$this->trimTrailingDecimalZeros = $trimTrailingDecimalZeros ?? $this->trimTrailingDecimalZeros ?? false;
$this->check(); $this->check();
} }
@ -133,6 +138,12 @@ class Currency implements Arrayable, JsonSerializable
return $this->rounding; return $this->rounding;
} }
/** Get the currency's setting for trimming trailing decimal zeros. */
public function trimTrailingDecimalZeros(): bool
{
return $this->trimTrailingDecimalZeros;
}
/** Convert the currency to a string (returns the code). */ /** Convert the currency to a string (returns the code). */
public function __toString() public function __toString()
{ {
@ -153,6 +164,7 @@ class Currency implements Arrayable, JsonSerializable
'rounding' => $this->rounding, 'rounding' => $this->rounding,
'decimalSeparator' => $this->decimalSeparator, 'decimalSeparator' => $this->decimalSeparator,
'thousandsSeparator' => $this->thousandsSeparator, 'thousandsSeparator' => $this->thousandsSeparator,
'trimTrailingDecimalZeros' => $this->trimTrailingDecimalZeros,
]; ];
} }

View file

@ -23,6 +23,14 @@ class PriceFormatter
$currency->thousandsSeparator(), $currency->thousandsSeparator(),
); );
if ($currency->trimTrailingDecimalZeros()) {
// Remove trailing zeros from the formatted string
$decimal = rtrim($decimal, '0');
// Once there are no more decimal values, remove the decimal separator as well
$decimal = rtrim($decimal, $currency->decimalSeparator());
}
return $currency->prefix() . $decimal . $currency->suffix(); return $currency->prefix() . $decimal . $currency->suffix();
} }

17
tests/Currencies/SEK.php Normal file
View file

@ -0,0 +1,17 @@
<?php
namespace ArchTech\Money\Tests\Currencies;
use ArchTech\Money\Currency;
class SEK extends Currency
{
protected string $code = 'SEK';
protected string $name = 'Swedish crown';
protected float $rate = 9.94;
protected int $mathDecimals = 4;
protected int $displayDecimals = 2;
protected int $rounding = 0;
protected string $suffix = ' kr';
protected bool $trimTrailingDecimalZeros = true;
}

View file

@ -28,6 +28,7 @@ test('currencies can be serialized to JSON', function () {
'rounding' => 2, 'rounding' => 2,
'decimalSeparator' => ',', 'decimalSeparator' => ',',
'thousandsSeparator' => '.', 'thousandsSeparator' => '.',
'trimTrailingDecimalZeros' => false,
]); ]);
}); });

View file

@ -5,8 +5,9 @@ use ArchTech\Money\Currency;
use ArchTech\Money\Money; use ArchTech\Money\Money;
use ArchTech\Money\Tests\Currencies\CZK; use ArchTech\Money\Tests\Currencies\CZK;
use ArchTech\Money\Tests\Currencies\EUR; use ArchTech\Money\Tests\Currencies\EUR;
use ArchTech\Money\Tests\Currencies\SEK;
beforeEach(fn () => currencies()->add([CZK::class, EUR::class])); beforeEach(fn () => currencies()->add([CZK::class, EUR::class, SEK::class]));
test('prefixes are applied', function () { test('prefixes are applied', function () {
expect(Money::fromDecimal(10.00, USD::class)->formatted())->toBe('$10.00'); expect(Money::fromDecimal(10.00, USD::class)->formatted())->toBe('$10.00');
@ -45,3 +46,15 @@ test('the format method accepts overrides', function () {
expect(Money::fromDecimal(10.45)->formatted(['decimalSeparator' => ',', 'prefix' => '$$$']))->toBe('$$$10,45'); expect(Money::fromDecimal(10.45)->formatted(['decimalSeparator' => ',', 'prefix' => '$$$']))->toBe('$$$10,45');
expect(Money::fromDecimal(10.45)->formatted(decimalSeparator: ',', suffix: ' USD'))->toBe('$10,45 USD'); expect(Money::fromDecimal(10.45)->formatted(decimalSeparator: ',', suffix: ' USD'))->toBe('$10,45 USD');
}); });
test('decimal zeros can be trimmed', function () {
// SEK uses decimal zero trimming
expect(Money::fromDecimal(10.00, SEK::class)->formatted())->toBe('10 kr');
expect(Money::fromDecimal(10.10, SEK::class)->formatted())->toBe('10.1 kr');
expect(Money::fromDecimal(10.12, SEK::class)->formatted())->toBe('10.12 kr');
// EUR does not use decimal zero trimming
expect(Money::fromDecimal(10.00, EUR::class)->formatted())->toBe('10.00 €');
expect(Money::fromDecimal(10.10, EUR::class)->formatted())->toBe('10.10 €');
expect(Money::fromDecimal(10.12, EUR::class)->formatted())->toBe('10.12 €');
});