diff --git a/commerce_discount.rules.inc b/commerce_discount.rules.inc index 8b19e29..beb56fd 100644 --- a/commerce_discount.rules.inc +++ b/commerce_discount.rules.inc @@ -1287,10 +1287,12 @@ function commerce_discount_add_price_component(EntityDrupalWrapper $line_item_wr // Calculate the updated amount and create a price array representing the // difference between it and the current amount. - $updated_amount = commerce_round(COMMERCE_ROUND_HALF_UP, $current_amount + $discount_amount['amount']); + $discount_amount['amount'] = commerce_round(COMMERCE_ROUND_HALF_DOWN, $discount_amount['amount']); + + $updated_amount = $current_amount + $discount_amount['amount']; $difference = array( - 'amount' => commerce_round(COMMERCE_ROUND_HALF_UP, $discount_amount['amount']), + 'amount' => $discount_amount['amount'], 'currency_code' => $discount_amount['currency_code'], 'data' => array( 'discount_name' => $discount_name, diff --git a/commerce_discount.test b/commerce_discount.test index 5aa3d7f..4742bd2 100644 --- a/commerce_discount.test +++ b/commerce_discount.test @@ -624,6 +624,40 @@ class CommerceDiscountTest extends CommerceDiscountTestBase { } /** + * Test rounding in discounts. + * + * @link https://www.drupal.org/node/2468943 + */ + public function testCommerceDiscountRounding() { + $commerce_discount = $this->createDiscount('product_discount', 'percentage', 0.01); + $discount_wrapper = entity_metadata_wrapper('commerce_discount', $commerce_discount); + $bulk_product = $this->createDummyProduct('BULK-PRODUCT', 'Bulk discount testing', 74); + // Create the order and apply discount. + $order = $this->createDummyOrder($this->store_customer->uid, array($bulk_product->product_id => 5000), 'completed'); + $order_wrapper = commerce_cart_order_refresh($order); + // Verify rounding came out properly. + $price = $order_wrapper->commerce_line_items->get(0)->commerce_total->amount_decimal->value(); + $this->assertEqual($price, 3663, 'Rounding does not inflate discount amount'); + + // For a $10.25 product with a 30% discount, this would produce as expected + // a $3.08 discount with a line item unit price of $7.17. + $commerce_discount = $this->createDiscount('product_discount', 'percentage', 0.3); + $product = $this->createDummyProduct('BC-APPLES', 'B.C. Apples', 1025); + // Create the order and apply discount. + $order = $this->createDummyOrder($this->store_customer->uid, array($product->product_id => 1), 'completed'); + $order_wrapper = commerce_cart_order_refresh($order); + // Verify rounding came out properly. + $line_item_wrapper = $order_wrapper->commerce_line_items->get(0); + $price = $line_item_wrapper->commerce_total->amount_decimal->value(); + $this->assertEqual($price, 717, 'Rounding does not inflate discount amount'); + // Check if the discount was added as a component to the line item. + $price_data = $line_item_wrapper->commerce_unit_price->data->value(); + $this->assertTrue($price_data['components'][1]['price']['amount'] == -308, 'Percentage product discount is added as a price component to the line item.'); + // Order total is correct. + $this->assertTrue($order_wrapper->commerce_order_total->amount->value() == 717, 'Percentage product discount was deducted correctly on order total.'); + } + + /** * Test discount compatibility strategies. * * Currently implemented strategies include: