1212use craft \commerce \elements \Order ;
1313use craft \commerce \models \LineItem ;
1414use craft \commerce \Plugin ;
15+ use craft \commerce \models \Store ;
1516use craftcommercetests \fixtures \OrdersFixture ;
1617use craftcommercetests \fixtures \PaymentCurrenciesFixture ;
18+ use craftcommercetests \fixtures \StoreFixture ;
1719use UnitTester ;
1820
1921/**
@@ -39,12 +41,20 @@ class OrderPaymentCurrencyRatesTest extends Unit
3941 */
4042 private array $ _deleteElementIds = [];
4143
44+ /**
45+ * @var Store|null
46+ */
47+ protected ?Store $ primaryStore = null ;
48+
4249 /**
4350 * @return array
4451 */
4552 public function _fixtures (): array
4653 {
4754 return [
55+ 'stores ' => [
56+ 'class ' => StoreFixture::class,
57+ ],
4858 'orders ' => [
4959 'class ' => OrdersFixture::class,
5060 ],
@@ -62,6 +72,7 @@ public function _fixtures(): array
6272 public function testPaymentCurrencyRatesCapturedOnCompletion (): void
6373 {
6474 $ order = new Order ();
75+ $ order ->storeId = $ this ->primaryStore ->id ;
6576 $ email = 'test-rates@example.com ' ;
6677 $ user = Craft::$ app ->getUsers ()->ensureUserByEmail ($ email );
6778 $ order ->setCustomer ($ user );
@@ -86,13 +97,15 @@ public function testPaymentCurrencyRatesCapturedOnCompletion(): void
8697 self ::assertNotNull ($ order ->paymentCurrencyRates );
8798 self ::assertIsArray ($ order ->paymentCurrencyRates );
8899
89- // Should have EUR and AUD from fixtures
90- self :: assertArrayHasKey ( ' EUR ' , $ order -> paymentCurrencyRates );
91- self :: assertArrayHasKey ( ' AUD ' , $ order -> paymentCurrencyRates );
100+ // Get the payment currencies for this store to verify
101+ $ paymentCurrencies = $ this -> pluginInstance -> getPaymentCurrencies ()
102+ -> getAllPaymentCurrencies ( $ this -> primaryStore -> id );
92103
93- // Verify the rates match the fixture data
94- self ::assertEquals (0.5 , $ order ->paymentCurrencyRates ['EUR ' ]);
95- self ::assertEquals (1.3 , $ order ->paymentCurrencyRates ['AUD ' ]);
104+ // Should have captured all payment currencies for the store
105+ foreach ($ paymentCurrencies as $ currency ) {
106+ self ::assertArrayHasKey ($ currency ->iso , $ order ->paymentCurrencyRates );
107+ self ::assertEquals ((float )$ currency ->rate , $ order ->paymentCurrencyRates [$ currency ->iso ]);
108+ }
96109
97110 $ this ->_deleteElementIds [] = $ order ->id ;
98111 $ this ->_deleteElementIds [] = $ user ->id ;
@@ -148,8 +161,19 @@ public function setPaymentCurrencyRatesDataProvider(): array
148161 */
149162 public function testGetPaymentAmountUsesSnapshotRateWhenEnabled (): void
150163 {
164+ // Get any non-primary payment currency from the store
165+ $ paymentCurrencies = $ this ->pluginInstance ->getPaymentCurrencies ()
166+ ->getAllPaymentCurrencies ($ this ->primaryStore ->id );
167+ $ testCurrency = $ paymentCurrencies ->firstWhere ('primary ' , false );
168+
169+ // Skip test if no non-primary payment currency available
170+ if (!$ testCurrency ) {
171+ $ this ->markTestSkipped ('No non-primary payment currency available in fixtures ' );
172+ }
173+
151174 $ order = new Order ();
152175 $ order ->id = 9999 ;
176+ $ order ->storeId = $ this ->primaryStore ->id ;
153177 $ order ->isCompleted = true ;
154178 $ order ->currency = 'USD ' ;
155179
@@ -159,20 +183,19 @@ public function testGetPaymentAmountUsesSnapshotRateWhenEnabled(): void
159183 $ lineItem ->qty = 1 ;
160184 $ order ->setLineItems ([$ lineItem ]);
161185
162- // Set snapshotted rate for EUR (different from fixture rate of 0.5 )
186+ // Set snapshotted rate (different from current rate)
163187 $ snapshotRate = 0.8 ;
164- $ order ->setPaymentCurrencyRates ([' EUR ' => $ snapshotRate, ' AUD ' => 1.5 ]);
188+ $ order ->setPaymentCurrencyRates ([$ testCurrency -> iso => $ snapshotRate ]);
165189
166- // Set payment currency to EUR
167- $ order ->setPaymentCurrency (' EUR ' );
190+ // Set payment currency
191+ $ order ->setPaymentCurrency ($ testCurrency -> iso );
168192
169- // Get the store and enable the snapshot setting
170- $ store = $ order ->getStore ();
171- $ store ->setUsesSnapshotPaymentCurrencyRate (true );
193+ // Enable the snapshot setting on the store
194+ $ this ->primaryStore ->setUsesSnapshotPaymentCurrencyRate (true );
172195
173196 // The payment amount should use the snapshotted rate
174- // Outstanding balance is 100 USD, snapshotted EUR rate is 0.8
175- // So payment amount should be 100 * 0.8 = 80 EUR
197+ // Outstanding balance is 100 USD, snapshotted rate is 0.8
198+ // So payment amount should be 100 * 0.8 = 80
176199 $ paymentAmount = $ order ->getPaymentAmount ();
177200
178201 self ::assertEquals (80 , $ paymentAmount );
@@ -185,8 +208,19 @@ public function testGetPaymentAmountUsesSnapshotRateWhenEnabled(): void
185208 */
186209 public function testGetPaymentAmountUsesCurrentRateWhenDisabled (): void
187210 {
211+ // Get any non-primary payment currency from the store
212+ $ paymentCurrencies = $ this ->pluginInstance ->getPaymentCurrencies ()
213+ ->getAllPaymentCurrencies ($ this ->primaryStore ->id );
214+ $ testCurrency = $ paymentCurrencies ->firstWhere ('primary ' , false );
215+
216+ // Skip test if no non-primary payment currency available
217+ if (!$ testCurrency ) {
218+ $ this ->markTestSkipped ('No non-primary payment currency available in fixtures ' );
219+ }
220+
188221 $ order = new Order ();
189222 $ order ->id = 9998 ;
223+ $ order ->storeId = $ this ->primaryStore ->id ;
190224 $ order ->isCompleted = true ;
191225 $ order ->currency = 'USD ' ;
192226
@@ -196,23 +230,21 @@ public function testGetPaymentAmountUsesCurrentRateWhenDisabled(): void
196230 $ lineItem ->qty = 1 ;
197231 $ order ->setLineItems ([$ lineItem ]);
198232
199- // Set snapshotted rate for EUR (different from fixture rate of 0.5 )
200- $ snapshotRate = 0.8 ;
201- $ order ->setPaymentCurrencyRates ([' EUR ' => $ snapshotRate ]);
233+ // Set snapshotted rate (different from current rate)
234+ $ snapshotRate = ( float ) $ testCurrency -> rate + 0.5 ; // Different from current
235+ $ order ->setPaymentCurrencyRates ([$ testCurrency -> iso => $ snapshotRate ]);
202236
203- // Set payment currency to EUR
204- $ order ->setPaymentCurrency (' EUR ' );
237+ // Set payment currency
238+ $ order ->setPaymentCurrency ($ testCurrency -> iso );
205239
206- // Get the store and disable the snapshot setting
207- $ store = $ order ->getStore ();
208- $ store ->setUsesSnapshotPaymentCurrencyRate (false );
240+ // Disable the snapshot setting on the store
241+ $ this ->primaryStore ->setUsesSnapshotPaymentCurrencyRate (false );
209242
210- // The payment amount should use the current rate from fixtures (0.5)
211- // Outstanding balance is 100 USD, current EUR rate is 0.5
212- // So payment amount should be 100 * 0.5 = 50 EUR
243+ // The payment amount should use the current rate (not snapshotted)
244+ $ expectedAmount = 100 * (float )$ testCurrency ->rate ;
213245 $ paymentAmount = $ order ->getPaymentAmount ();
214246
215- self ::assertEquals (50 , $ paymentAmount );
247+ self ::assertEquals ($ expectedAmount , $ paymentAmount );
216248 }
217249
218250 /**
@@ -222,8 +254,19 @@ public function testGetPaymentAmountUsesCurrentRateWhenDisabled(): void
222254 */
223255 public function testIncompleteOrderDoesNotUseSnapshotRate (): void
224256 {
257+ // Get any non-primary payment currency from the store
258+ $ paymentCurrencies = $ this ->pluginInstance ->getPaymentCurrencies ()
259+ ->getAllPaymentCurrencies ($ this ->primaryStore ->id );
260+ $ testCurrency = $ paymentCurrencies ->firstWhere ('primary ' , false );
261+
262+ // Skip test if no non-primary payment currency available
263+ if (!$ testCurrency ) {
264+ $ this ->markTestSkipped ('No non-primary payment currency available in fixtures ' );
265+ }
266+
225267 $ order = new Order ();
226268 $ order ->id = 9997 ;
269+ $ order ->storeId = $ this ->primaryStore ->id ;
227270 $ order ->isCompleted = false ; // Order not completed
228271 $ order ->currency = 'USD ' ;
229272
@@ -233,21 +276,21 @@ public function testIncompleteOrderDoesNotUseSnapshotRate(): void
233276 $ lineItem ->qty = 1 ;
234277 $ order ->setLineItems ([$ lineItem ]);
235278
236- // Set snapshotted rate (shouldn't be used)
237- $ order ->setPaymentCurrencyRates (['EUR ' => 0.8 ]);
279+ // Set snapshotted rate (shouldn't be used because order is not completed)
280+ $ snapshotRate = (float )$ testCurrency ->rate + 0.5 ; // Different from current
281+ $ order ->setPaymentCurrencyRates ([$ testCurrency ->iso => $ snapshotRate ]);
238282
239- // Set payment currency to EUR
240- $ order ->setPaymentCurrency (' EUR ' );
283+ // Set payment currency
284+ $ order ->setPaymentCurrency ($ testCurrency -> iso );
241285
242- // Get the store and enable the snapshot setting
243- $ store = $ order ->getStore ();
244- $ store ->setUsesSnapshotPaymentCurrencyRate (true );
286+ // Enable the snapshot setting on the store
287+ $ this ->primaryStore ->setUsesSnapshotPaymentCurrencyRate (true );
245288
246289 // The payment amount should use the current rate because order is not completed
247- // Current EUR rate from fixtures is 0.5
290+ $ expectedAmount = 100 * ( float ) $ testCurrency -> rate ;
248291 $ paymentAmount = $ order ->getPaymentAmount ();
249292
250- self ::assertEquals (50 , $ paymentAmount );
293+ self ::assertEquals ($ expectedAmount , $ paymentAmount );
251294 }
252295
253296 /**
@@ -257,8 +300,19 @@ public function testIncompleteOrderDoesNotUseSnapshotRate(): void
257300 */
258301 public function testOrderWithoutSnapshotFallsBackToCurrentRate (): void
259302 {
303+ // Get any non-primary payment currency from the store
304+ $ paymentCurrencies = $ this ->pluginInstance ->getPaymentCurrencies ()
305+ ->getAllPaymentCurrencies ($ this ->primaryStore ->id );
306+ $ testCurrency = $ paymentCurrencies ->firstWhere ('primary ' , false );
307+
308+ // Skip test if no non-primary payment currency available
309+ if (!$ testCurrency ) {
310+ $ this ->markTestSkipped ('No non-primary payment currency available in fixtures ' );
311+ }
312+
260313 $ order = new Order ();
261314 $ order ->id = 9996 ;
315+ $ order ->storeId = $ this ->primaryStore ->id ;
262316 $ order ->isCompleted = true ;
263317 $ order ->currency = 'USD ' ;
264318
@@ -271,17 +325,17 @@ public function testOrderWithoutSnapshotFallsBackToCurrentRate(): void
271325 // Don't set snapshotted rates (simulating old order before feature)
272326 $ order ->paymentCurrencyRates = null ;
273327
274- // Set payment currency to EUR
275- $ order ->setPaymentCurrency (' EUR ' );
328+ // Set payment currency
329+ $ order ->setPaymentCurrency ($ testCurrency -> iso );
276330
277- // Get the store and enable the snapshot setting
278- $ store = $ order ->getStore ();
279- $ store ->setUsesSnapshotPaymentCurrencyRate (true );
331+ // Enable the snapshot setting on the store
332+ $ this ->primaryStore ->setUsesSnapshotPaymentCurrencyRate (true );
280333
281334 // The payment amount should use the current rate because no snapshot exists
335+ $ expectedAmount = 100 * (float )$ testCurrency ->rate ;
282336 $ paymentAmount = $ order ->getPaymentAmount ();
283337
284- self ::assertEquals (50 , $ paymentAmount );
338+ self ::assertEquals ($ expectedAmount , $ paymentAmount );
285339 }
286340
287341 /**
@@ -325,6 +379,7 @@ protected function _before(): void
325379 parent ::_before ();
326380
327381 $ this ->pluginInstance = Plugin::getInstance ();
382+ $ this ->primaryStore = $ this ->pluginInstance ->getStores ()->getPrimaryStore ();
328383 }
329384
330385 /**
0 commit comments