Hey Everybody,

I have noticed and odd peculiar thing with Price() library... At the moment I am importing multiple products via cron jobs and creating products / product variations & their prices programatically...

But I have came a odd behaviour when calculating price's... Issue that when using ->multiply($number) method price is being saved with 6 decimal places... This causes a lot of oddities within the code for instance:

In UK store, I am pulling prices without VAT

//ItemA - £1416.67
$price = new Price('1416.67', 'GBP');
$with_vat = $price->multiply('1.2');

echo $price->getNumber(); // 1416.67
echo $with_vat->getNumber(); // 1700.004

So total price becomes 1700.004 which becomes an issue when selling 2 or more items as it would add few £0.01 to the total sum.

At moment I am not using this ->multiply() method anymore and calculating correct price before passing it to the ProductVariation price...

Also this would essentially occur any time ->multiple() used... I would propose to limit all prices to 2 decimal numbers...


  /**
   * Multiplies the current price by the given number.
   *
   * @param string $number
   *   The number.
   *
   * @param int $decimal
   *   Decimal places
   *
   * @return static
   *   The resulting price.
   */
  public function multiply($number, $decimal = 2) {
    $new_number = Calculator::multiply($this->number, $number, $decimal);
    return new static($new_number, $this->currencyCode);
  }

  /**
   * Divides the current price by the given number.
   *
   * @param string $number
   *   The number.
   * 
   * @param int $decimal
   *   Decimal places
   *
   * @return static
   *   The resulting price.
   */
  public function divide($number, $decimal = 2) {
    $new_number = Calculator::divide($this->number, $number, $decimal);
    return new static($new_number, $this->currencyCode);
  }

So that it would be possible to pass $decimal variable to control price output? This is just an idea....

Cheers,

Comments

puogintas created an issue. See original summary.

povilas uogintas’s picture

Priority: Normal » Minor
bojanz’s picture

Category: Feature request » Support request

The Price object doesn't round. That would not be practical for cases that require special rounding, such as taxes.

You need to get the commerce_price.rounder object, and then pass the price to $rounder->round().

povilas uogintas’s picture

Thanks!

This $rounder object solves everything and will keep code tidy!

Cheers,

povilas uogintas’s picture

Status: Active » Fixed
povilas uogintas’s picture

Issue summary: View changes

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

filipetakanap’s picture

I have the same issue and i'm failing to understand:
"You need to get the commerce_price.rounder object, and then pass the price to $rounder->round()."

I guess it is something like this:

$rounder = \Drupal::service('commerce_price.rounder');
    $adjusted_unit_price = $rounder->round($adjusted_unit_price);

But what variable in Price.php do I convert?

Thanks