@@ -64,4 +64,30 @@ public function it_distributes_fixed_amount_proportionally_by_line_item_value()
6464 $ this ->assertEquals (75 , $ amountLine2 );
6565 $ this ->assertEquals (100 , $ amountLine1 + $ amountLine2 );
6666 }
67+
68+ /**
69+ * @see https://github.com/duncanmcclean/statamic-cargo/issues/164
70+ */
71+ #[Test]
72+ public function it_distributes_fixed_amount_without_rounding_errors_when_not_perfectly_divisible ()
73+ {
74+ // When 1000 (CHF 10) is divided by 3 equal line items, each gets 333.33...
75+ // Using floor() would give 333 + 333 + 333 = 999, losing 1 cent
76+ $ discount = Discount::make ()->type ('amount_off ' )->set ('amount_off ' , 1000 );
77+
78+ $ cart = Cart::make ();
79+ $ cart ->lineItems ()->create (['id ' => 'line1 ' , 'total ' => 3333 ]);
80+ $ cart ->lineItems ()->create (['id ' => 'line2 ' , 'total ' => 3333 ]);
81+ $ cart ->lineItems ()->create (['id ' => 'line3 ' , 'total ' => 3334 ]);
82+
83+ $ discountType = (new AmountOff )->setDiscount ($ discount );
84+
85+ $ amountLine1 = $ discountType ->calculate ($ cart , $ cart ->lineItems ()->find ('line1 ' ));
86+ $ amountLine2 = $ discountType ->calculate ($ cart , $ cart ->lineItems ()->find ('line2 ' ));
87+ $ amountLine3 = $ discountType ->calculate ($ cart , $ cart ->lineItems ()->find ('line3 ' ));
88+
89+ // The total discount applied should equal the full discount amount (1000)
90+ // not 999 due to rounding errors
91+ $ this ->assertEquals (1000 , $ amountLine1 + $ amountLine2 + $ amountLine3 );
92+ }
6793}
0 commit comments