Skip to content

[5.3.8]: Money\Exception\ParserException] Cannot parse "1.0658141036402E-14" to Money. #3997

@ragnarfrosti

Description

@ragnarfrosti

What happened?

We have been seeing couple of ParseExceptions (Cannot parse "x.xxxxxxxx-14" to Money) in our logs recently.

This problem appears rarely, so it was hard to find out what was causing it, but the issue seems to be with some of our products (or some specific prices), and when a percentage discount is applied to the order for these products/prices when $this->getAdjustmentsTotal() is called.

In your Discount adjuster (adjusters/Discount.php) the adjustment amount is set:

$adjustment->amount = $amountOfPercentDiscount;

where the $amountOfPercentDiscount is the sum of two already rounded amounts. But that doesn't seem to be enough for some reason, but if I round the amount that is set as $adjusment->amount we get rid of the error:

Before:
Image

After:
Image

The error:

Money\Exception\ParserException
Cannot parse "3.5527136788005E-15" to Money.

    1. in /var/www/html/vendor/moneyphp/money/src/Parser/DecimalMoneyParser.php at line 46
    37383940414243444546474849505152535455

            }
     
            $decimal = trim($money);
     
            if ($decimal === '') {
                return new Money(0, $fallbackCurrency);
            }
     
            if (! preg_match(self::DECIMAL_PATTERN, $decimal, $matches) || ! isset($matches['digits'])) {
                throw new ParserException(sprintf('Cannot parse "%s" to Money.', $decimal));
            }
     
            $negative = isset($matches['sign']) && $matches['sign'] === '-';
     
            $decimal = $matches['digits'];
     
            if ($negative) {
                $decimal = '-' . $decimal;
            }

    2. in /var/www/html/vendor/moneyphp/money/src/Teller.php at line 364 – Money\Parser\DecimalMoneyParser::parse()
    358359360361362363364365366367368369370

         * Converts a monetary amount to a Money object.
         *
         * @param mixed $amount a monetary amount
         */
        public function convertToMoney(mixed $amount): Money
        {
            return $this->parser->parse((string) $amount, $this->currency);
        }
     
        /**
         * Converts an array of monetary amounts to an array of Money objects.
         *
         * @param array<int|string, mixed> $amounts an array of monetary amounts

    3. in /var/www/html/vendor/moneyphp/money/src/Teller.php at line 117 – Money\Teller::convertToMoney()
    111112113114115116117118119120121122123

         * @return string the calculated monetary amount
         */
        public function add(mixed $amount, mixed $other, mixed ...$others): string
        {
            return $this->convertToString(
                $this->convertToMoney($amount)->add(
                    $this->convertToMoney($other),
                    ...$this->convertToMoneyArray($others)
                )
            );
        }
     
        /**

    4. in /var/www/html/vendor/craftcms/commerce/src/elements/Order.php at line 2683 – Money\Teller::add()
    2677267826792680268126822683268426852686268726882689

     
        /**
         * Get the total price of the order, whose minimum value is enforced by the configured {@link Store::getMinimumTotalPriceStrategy() strategy set for minimum total price}.
         */
        public function getTotalPrice(): float
        {
            $total = (float)$this->getTeller()->add($this->getItemSubtotal(), $this->getAdjustmentsTotal());
            // Don't get the pre-rounded total.
            $strategy = $this->getStore()->getMinimumTotalPriceStrategy();
     
            if ($strategy === Store::MINIMUM_TOTAL_PRICE_STRATEGY_ZERO) {
                return (float)$this->getTeller()->max(0, $total);
            }


Craft CMS version

5.6.17

Craft Commerce version

5.3.8

PHP version

No response

Operating system and version

No response

Database type and version

No response

Image driver and version

No response

Installed plugins and versions

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions