Skip to content
This repository was archived by the owner on Oct 24, 2023. It is now read-only.

Commit 95722b9

Browse files
committed
feat(Money): support high precision money
Closes #410
1 parent 49ff19e commit 95722b9

File tree

5 files changed

+199
-6
lines changed

5 files changed

+199
-6
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
/**
3+
*/
4+
5+
namespace Commercetools\Core\Model\Common;
6+
7+
/**
8+
* @package Commercetools\Core\Model\Common
9+
*
10+
* @method string getCurrencyCode()
11+
* @method CentPrecisionMoney setCurrencyCode(string $currencyCode = null)
12+
* @method int getCentAmount()
13+
* @method CentPrecisionMoney setCentAmount(int $centAmount = null)
14+
* @method string getType()
15+
* @method CentPrecisionMoney setType(string $type = null)
16+
* @method string getFractionDigits()
17+
* @method CentPrecisionMoney setFractionDigits(string $fractionDigits = null)
18+
*/
19+
class CentPrecisionMoney extends Money
20+
{
21+
/**
22+
* @inheritDoc
23+
*/
24+
public function __construct(array $data = [], $context = null)
25+
{
26+
$data[static::TYPE] = static::TYPE_CENT_PRECISION;
27+
parent::__construct($data, $context);
28+
}
29+
30+
public function fieldDefinitions()
31+
{
32+
return [
33+
static::CURRENCY_CODE => [self::TYPE => 'string'],
34+
static::CENT_AMOUNT => [self::TYPE => 'int'],
35+
static::TYPE => [self::TYPE => 'string'],
36+
static::FRACTION_DIGITS => [self::TYPE => 'string']
37+
];
38+
}
39+
40+
/**
41+
* @param $currencyCode
42+
* @param $centAmount
43+
* @param Context|callable $context
44+
* @return Money
45+
*/
46+
public static function ofCurrencyAndAmount($currencyCode, $centAmount, $context = null)
47+
{
48+
$money = static::of($context);
49+
return $money->setCurrencyCode($currencyCode)
50+
->setCentAmount($centAmount);
51+
}
52+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?php
2+
/**
3+
*/
4+
5+
namespace Commercetools\Core\Model\Common;
6+
7+
/**
8+
* @package Commercetools\Core\Model\Common
9+
* @link https://docs.commercetools.com/http-api-types.html#money
10+
* @method string getCurrencyCode()
11+
* @method int getCentAmount()
12+
* @method HighPrecisionMoney setCurrencyCode(string $currencyCode = null)
13+
* @method HighPrecisionMoney setCentAmount(int $centAmount = null)
14+
* @method string getType()
15+
* @method HighPrecisionMoney setType(string $type = null)
16+
* @method string getFractionDigits()
17+
* @method HighPrecisionMoney setFractionDigits(string $fractionDigits = null)
18+
* @method int getPreciseAmount()
19+
* @method HighPrecisionMoney setPreciseAmount(int $preciseAmount = null)
20+
* @method string getHighPrecision()
21+
* @method HighPrecisionMoney setHighPrecision(string $highPrecision = null)
22+
*/
23+
class HighPrecisionMoney extends Money
24+
{
25+
const PRECISE_AMOUNT = 'preciseAmount';
26+
27+
/**
28+
* @inheritDoc
29+
*/
30+
public function __construct(array $data = [], $context = null)
31+
{
32+
$data[static::TYPE] = static::TYPE_HIGH_PRECISION;
33+
parent::__construct($data, $context);
34+
}
35+
36+
public function fieldDefinitions()
37+
{
38+
return [
39+
static::CURRENCY_CODE => [self::TYPE => 'string'],
40+
static::CENT_AMOUNT => [self::TYPE => 'int'],
41+
static::TYPE => [self::TYPE => 'string'],
42+
static::FRACTION_DIGITS => [self::TYPE => 'string'],
43+
static::PRECISE_AMOUNT => [self::TYPE => 'int'],
44+
];
45+
}
46+
47+
/**
48+
* @param string $currencyCode
49+
* @param int $amount
50+
* @param int $fractionDigits
51+
* @param Context|callable $context
52+
* @return HighPrecisionMoney
53+
*/
54+
public static function ofCurrencyAmountAndFraction($currencyCode, $amount, $fractionDigits, $context = null)
55+
{
56+
$money = static::of($context);
57+
return $money->setCurrencyCode($currencyCode)
58+
->setPreciseAmount($amount)
59+
->setFractionDigits($fractionDigits);
60+
}
61+
62+
/**
63+
* @param $currencyCode
64+
* @param $centAmount
65+
* @param Context|callable $context
66+
* @return HighPrecisionMoney|Money
67+
*/
68+
public static function ofCurrencyAndAmount($currencyCode, $centAmount, $context = null)
69+
{
70+
$money = static::of($context);
71+
return $money->setCurrencyCode($currencyCode)
72+
->setPreciseAmount($centAmount)
73+
->setFractionDigits(2);
74+
}
75+
}

src/Core/Model/Common/Money.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,26 @@
1313
* @method int getCentAmount()
1414
* @method Money setCurrencyCode(string $currencyCode = null)
1515
* @method Money setCentAmount(int $centAmount = null)
16+
* @method string getType()
17+
* @method Money setType(string $type = null)
18+
* @method string getFractionDigits()
19+
* @method Money setFractionDigits(string $fractionDigits = null)
1620
*/
1721
class Money extends JsonObject
1822
{
1923
const CURRENCY_CODE = 'currencyCode';
2024
const CENT_AMOUNT = 'centAmount';
25+
const FRACTION_DIGITS = 'fractionDigits';
26+
const TYPE_CENT_PRECISION = 'centPrecision';
27+
const TYPE_HIGH_PRECISION = 'highPrecision';
28+
29+
/**
30+
* @inheritDoc
31+
*/
32+
public function __construct(array $data = [], $context = null)
33+
{
34+
parent::__construct($data, $context);
35+
}
2136

2237
public function fieldDefinitions()
2338
{
@@ -27,6 +42,31 @@ public function fieldDefinitions()
2742
];
2843
}
2944

45+
/**
46+
* @param array $data
47+
* @param Context|callable $context
48+
* @return Money
49+
*/
50+
public static function fromArray(array $data, $context = null)
51+
{
52+
if (get_called_class() == Money::class && isset($data[static::TYPE])) {
53+
$className = static::moneyType($data[static::TYPE]);
54+
if (class_exists($className)) {
55+
return new $className($data, $context);
56+
}
57+
}
58+
return new static($data, $context);
59+
}
60+
61+
protected static function moneyType($type)
62+
{
63+
$types = [
64+
static::TYPE_CENT_PRECISION => CentPrecisionMoney::class,
65+
static::TYPE_HIGH_PRECISION => HighPrecisionMoney::class,
66+
];
67+
return isset($types[$type]) ? $types[$type] : Money::class;
68+
}
69+
3070
/**
3171
* @return string
3272
*/

tests/unit/Model/Common/MoneyTest.php

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,31 @@ public function testDefaultFormatEUR()
3939
$context = Context::of()->setLocale('de_DE');
4040
$money = Money::fromArray(['currencyCode' => 'EUR', 'centAmount' => 100], $context);
4141
$money = htmlentities((string)$money);
42-
$this->assertEquals('1,00&nbsp;&euro;', $money);
42+
$this->assertSame('1,00&nbsp;&euro;', $money);
43+
}
44+
45+
public function testCentPrecision()
46+
{
47+
$this->assertInstanceOf(
48+
CentPrecisionMoney::class,
49+
Money::fromArray(['currencyCode' => 'EUR', 'centAmount' => 100, 'type' => Money::TYPE_CENT_PRECISION])
50+
);
51+
52+
}
53+
54+
public function testHighPrecision()
55+
{
56+
$this->assertInstanceOf(
57+
HighPrecisionMoney::class,
58+
Money::fromArray(
59+
[
60+
'currencyCode' => 'EUR',
61+
'centAmount' => 100,
62+
'preciseAmount' => 1000,
63+
'fractionDigits' => 3,
64+
'type' => Money::TYPE_HIGH_PRECISION,
65+
]
66+
)
67+
);
4368
}
4469
}

tests/unit/Model/RamlModelTest.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -237,11 +237,12 @@ function ($fixture) use ($classNameField){
237237
return [$fixture[$classNameField], $fixture['fields']];
238238
},
239239
array_filter(
240-
$fixtures,
241-
function ($fixture) use ($modelClasses) {
242-
return count($fixture['fields']) > 0;
243-
}
244-
));
240+
$fixtures,
241+
function ($fixture) use ($modelClasses) {
242+
return count($fixture['fields']) > 0;
243+
}
244+
)
245+
);
245246
}
246247

247248
private function getRamlTypes() {

0 commit comments

Comments
 (0)