diff --git a/composer.json b/composer.json index 7377f01e..acee1f3e 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,6 @@ "doctrine/annotations": "^1.6", "florianv/swap": "^4.0", "friendsofsymfony/ckeditor-bundle": "^2.0", - "gerardojbaez/money": "^0.3.1", "nyholm/psr7": "^1.1", "ocramius/proxy-manager": "2.1.*", "omines/datatables-bundle": "^0.2.2", @@ -43,7 +42,8 @@ "twig/extensions": "^1.5", "twig/extra-bundle": "3.x-dev", "twig/intl-extra": "3.x-dev", - "webmozart/assert": "^1.4" + "webmozart/assert": "^1.4", + "ext-bcmath": "*" }, "require-dev": { "roave/security-advisories": "dev-master", diff --git a/composer.lock b/composer.lock index f988abc9..52855fe3 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "f66e6f1196a0dbebea3453e306b7e58f", + "content-hash": "ce7f2c4f8eb45f90abbc99599f3fbe83", "packages": [ { "name": "clue/stream-filter", @@ -1570,54 +1570,6 @@ ], "time": "2019-04-15T16:29:43+00:00" }, - { - "name": "gerardojbaez/money", - "version": "v0.3.1", - "source": { - "type": "git", - "url": "https://github.com/gerardojbaez/money.git", - "reference": "1a29ca19899fad8ae559e9f2c982815ea21f8a6c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/gerardojbaez/money/zipball/1a29ca19899fad8ae559e9f2c982815ea21f8a6c", - "reference": "1a29ca19899fad8ae559e9f2c982815ea21f8a6c", - "shasum": "" - }, - "require": { - "php": ">=5.5.9" - }, - "require-dev": { - "phpunit/phpunit": "5.4.*" - }, - "type": "library", - "autoload": { - "psr-4": { - "Gerardojbaez\\Money\\": "src/" - }, - "files": [ - "src/helpers.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gerardo Báez", - "email": "gerardojbaez@gmail.com" - } - ], - "description": "A simple and cross-platform alternative to PHP money_format(). 91 currencies supported, including INR.", - "keywords": [ - "currency", - "formatter", - "money", - "money_format" - ], - "time": "2018-02-24T18:59:00+00:00" - }, { "name": "guzzlehttp/guzzle", "version": "6.3.3", @@ -7379,16 +7331,16 @@ }, { "name": "zendframework/zend-code", - "version": "3.3.1", + "version": "3.3.2", "source": { "type": "git", "url": "https://github.com/zendframework/zend-code.git", - "reference": "c21db169075c6ec4b342149f446e7b7b724f95eb" + "reference": "936fa7ad4d53897ea3e3eb41b5b760828246a20b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-code/zipball/c21db169075c6ec4b342149f446e7b7b724f95eb", - "reference": "c21db169075c6ec4b342149f446e7b7b724f95eb", + "url": "https://api.github.com/repos/zendframework/zend-code/zipball/936fa7ad4d53897ea3e3eb41b5b760828246a20b", + "reference": "936fa7ad4d53897ea3e3eb41b5b760828246a20b", "shasum": "" }, "require": { @@ -7396,10 +7348,10 @@ "zendframework/zend-eventmanager": "^2.6 || ^3.0" }, "require-dev": { - "doctrine/annotations": "~1.0", + "doctrine/annotations": "^1.0", "ext-phar": "*", - "phpunit/phpunit": "^6.2.3", - "zendframework/zend-coding-standard": "^1.0.0", + "phpunit/phpunit": "^7.5.15", + "zendframework/zend-coding-standard": "^1.0", "zendframework/zend-stdlib": "^2.7 || ^3.0" }, "suggest": { @@ -7422,13 +7374,13 @@ "license": [ "BSD-3-Clause" ], - "description": "provides facilities to generate arbitrary code using an object oriented interface", - "homepage": "https://github.com/zendframework/zend-code", + "description": "Extensions to the PHP Reflection API, static code scanning, and code generation", "keywords": [ + "ZendFramework", "code", - "zf2" + "zf" ], - "time": "2018-08-13T20:36:59+00:00" + "time": "2019-08-31T14:14:34+00:00" }, { "name": "zendframework/zend-eventmanager", @@ -7538,16 +7490,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.2.3", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "e612609022e935f3d0337c1295176505b41188c8" + "reference": "97e59c7a16464196a8b9c77c47df68e4a39a45c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/e612609022e935f3d0337c1295176505b41188c8", - "reference": "e612609022e935f3d0337c1295176505b41188c8", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/97e59c7a16464196a8b9c77c47df68e4a39a45c4", + "reference": "97e59c7a16464196a8b9c77c47df68e4a39a45c4", "shasum": "" }, "require": { @@ -7585,7 +7537,7 @@ "parser", "php" ], - "time": "2019-08-12T20:17:41+00:00" + "time": "2019-09-01T07:51:21+00:00" }, { "name": "roave/security-advisories", @@ -8476,7 +8428,8 @@ "ext-ctype": "*", "ext-iconv": "*", "ext-intl": "*", - "ext-mbstring": "*" + "ext-mbstring": "*", + "ext-bcmath": "*" }, "platform-dev": [] } diff --git a/config/services.yaml b/config/services.yaml index 5374009d..7c696fba 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -56,6 +56,9 @@ services: arguments: $base_currency: '%default_currency%' + App\Services\MoneyFormatter: + arguments: + $base_currency: '%default_currency%' # add more service definitions when explicit configuration is needed # please note that last definitions always *replace* previous ones diff --git a/src/Entity/PriceInformations/Orderdetail.php b/src/Entity/PriceInformations/Orderdetail.php index f457a492..13530816 100644 --- a/src/Entity/PriceInformations/Orderdetail.php +++ b/src/Entity/PriceInformations/Orderdetail.php @@ -215,7 +215,7 @@ class Orderdetail extends DBElement /** * Get all pricedetails. * - * @return Pricedetail[] all pricedetails as a one-dimensional array of Pricedetails objects, + * @return Pricedetail[]|Collection all pricedetails as a one-dimensional array of Pricedetails objects, * sorted by minimum discount quantity * * @throws Exception if there was an error @@ -250,22 +250,21 @@ class Orderdetail extends DBElement /** * Get the price for a specific quantity. - * @param int $quantity this is the quantity to choose the correct pricedetails - * @param int|null $multiplier * This is the multiplier which will be applied to every single price + * @param float $quantity this is the quantity to choose the correct pricedetails + * @param string|float|int $multiplier * This is the multiplier which will be applied to every single price * * If you pass NULL, the number from $quantity will be used * - * @return float float: the price as a float number (if "$as_money_string == false") + * @return string|null: the price as a bcmath string. Null if there are no orderdetails for the given quantity * * @throws Exception if there are no pricedetails for the choosed quantity * (for example, there are only one pricedetails with the minimum discount quantity '10', * but the choosed quantity is '5' --> the price for 5 parts is not defined!) * @throws Exception if there was an error */ - public function getPrice(int $quantity = 1, $multiplier = null) : ?float + public function getPrice(float $quantity = 1, $multiplier = 1) : ?string { - if (($quantity === 0) && ($multiplier === null)) { - return 0.0; + return "0.0"; } $all_pricedetails = $this->getPricedetails(); diff --git a/src/Entity/PriceInformations/Pricedetail.php b/src/Entity/PriceInformations/Pricedetail.php index f85c04c5..2eaa0519 100644 --- a/src/Entity/PriceInformations/Pricedetail.php +++ b/src/Entity/PriceInformations/Pricedetail.php @@ -79,6 +79,8 @@ use Symfony\Component\Validator\Constraints as Assert; class Pricedetail extends DBElement { + public const PRICE_PRECISION = 5; + use TimestampTrait; /** @@ -125,6 +127,10 @@ class Pricedetail extends DBElement */ protected $manual_input = true; + public function __construct() + { + bcscale(static::PRICE_PRECISION); + } /******************************************************************************** * @@ -162,21 +168,34 @@ class Pricedetail extends DBElement return $this->price; } + /** + * Returns the price associated with this pricedetail as integer. + * It is given in current currency and for the price related quantity, in parts of 0.00001 (5 digits) + * @return int + */ + public function getPriceInt() : int + { + return (int) str_replace('.', '', $this->price); + } + /** * Get the price for a single unit in the currency associated with this price detail. * - * @param int $multiplier The returned price (float or string) will be multiplied + * @param float $multiplier The returned price (float or string) will be multiplied * with this multiplier. * * You will get the price for $multiplier parts. If you want the price which is stored * in the database, you have to pass the "price_related_quantity" count as $multiplier. * - * @return float the price as a float number + * @return string the price as a bcmath string */ - public function getPricePerUnit(int $multiplier = 1) : float + public function getPricePerUnit($multiplier = 1) : string { - return ($this->price * $multiplier) / $this->price_related_quantity; + $multiplier = (string) $multiplier; + $tmp = bcmul($this->price, $multiplier, static::PRICE_PRECISION); + return bcdiv($tmp, (string) $this->price_related_quantity, static::PRICE_PRECISION); + //return ($this->price * $multiplier) / $this->price_related_quantity; } /** @@ -266,7 +285,7 @@ class Pricedetail extends DBElement /** * Set the price. * - * @param float $new_price the new price as a float number + * @param string $new_price the new price as a float number * * * This is the price for "price_related_quantity" parts!! * * Example: if "price_related_quantity" is '10', @@ -274,7 +293,7 @@ class Pricedetail extends DBElement * * @return self */ - public function setPrice(float $new_price): Pricedetail + public function setPrice(string $new_price): Pricedetail { //Assert::natural($new_price, 'The new price must be positive! Got %s!'); diff --git a/src/Services/MoneyFormatter.php b/src/Services/MoneyFormatter.php index 7cb984cc..b3dc8d33 100644 --- a/src/Services/MoneyFormatter.php +++ b/src/Services/MoneyFormatter.php @@ -32,28 +32,38 @@ namespace App\Services; -use Gerardojbaez\Money\Money; -use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface; +use App\Entity\PriceInformations\Currency; +use Locale; class MoneyFormatter { - private $params; + protected $base_currency; + protected $locale; - public function __construct(ContainerBagInterface $params) + public function __construct(string $base_currency) { - $this->params = $params; + $this->base_currency = $base_currency; + $this->locale = Locale::getDefault(); } - public function format($amount, string $currency = "") : string + /** + * @param string $value The value that should be + * @param Currency|null $currency + * @param int $decimals + * @return string + */ + public function format(string $value, ?Currency $currency = null, $decimals = 5) { - if ($currency === "") { - $currency = $this->params->get("default_currency"); + $iso_code = $this->base_currency; + if ($currency !== null && !empty($currency->getIsoCode())) { + $iso_code = $currency->getIsoCode(); } - $money = new Money($amount, $currency); + $number_formatter = new \NumberFormatter($this->locale, \NumberFormatter::CURRENCY); + $number_formatter->setAttribute(\NumberFormatter::FRACTION_DIGITS, $decimals); - return $money->format(); + return $number_formatter->formatCurrency((float) $value, $iso_code); } } \ No newline at end of file diff --git a/src/Twig/AppExtension.php b/src/Twig/AppExtension.php index 56ccd17d..966fb126 100644 --- a/src/Twig/AppExtension.php +++ b/src/Twig/AppExtension.php @@ -32,11 +32,13 @@ namespace App\Twig; use App\Entity\Attachments\Attachment; use App\Entity\Base\DBElement; use App\Entity\Parts\MeasurementUnit; +use App\Entity\PriceInformations\Currency; use App\Services\AmountFormatter; use App\Services\EntityURLGenerator; use App\Services\MoneyFormatter; use App\Services\SIFormatter; use App\Services\TreeBuilder; +use Money\Currencies; use Symfony\Component\Cache\Adapter\AdapterInterface; use Symfony\Component\Serializer\SerializerInterface; use Twig\Extension\AbstractExtension; @@ -123,9 +125,9 @@ class AppExtension extends AbstractExtension return $item->get(); } - public function formatCurrency($amount, $currency = "") + public function formatCurrency($amount, Currency $currency = null, int $decimals = 5) { - return $this->moneyFormatter->format($amount, $currency); + return $this->moneyFormatter->format($amount, $currency, $decimals); } public function siFormat($value, $unit, $decimals = 2) diff --git a/symfony.lock b/symfony.lock index eb11f259..561a210c 100644 --- a/symfony.lock +++ b/symfony.lock @@ -117,9 +117,6 @@ "./config/packages/fos_ckeditor.yaml" ] }, - "gerardojbaez/money": { - "version": "v0.3.1" - }, "guzzlehttp/guzzle": { "version": "6.3.3" }, diff --git a/templates/Parts/info/_order_infos.html.twig b/templates/Parts/info/_order_infos.html.twig index 4d2270ee..8907ed7c 100644 --- a/templates/Parts/info/_order_infos.html.twig +++ b/templates/Parts/info/_order_infos.html.twig @@ -35,10 +35,11 @@ {{ detail.MinDiscountQuantity }}