diff --git a/packages/core/src/DiscountTypes/BuyXGetY.php b/packages/core/src/DiscountTypes/BuyXGetY.php index d1d40606a3..41714ca101 100644 --- a/packages/core/src/DiscountTypes/BuyXGetY.php +++ b/packages/core/src/DiscountTypes/BuyXGetY.php @@ -271,7 +271,7 @@ private function processAutomaticRewards(CartContract $cart, int $remainingRewar if (! $rewardLine) { $rewardLine = $cart->lines()->make([ - 'purchasable_type' => get_class($purchasable), + 'purchasable_type' => $purchasable->getMorphClass(), 'purchasable_id' => $purchasable->id, 'quantity' => 1, ]); diff --git a/tests/core/Unit/DiscountTypes/BuyXGetYTest.php b/tests/core/Unit/DiscountTypes/BuyXGetYTest.php index 31a4b67da4..c6c31d6356 100644 --- a/tests/core/Unit/DiscountTypes/BuyXGetYTest.php +++ b/tests/core/Unit/DiscountTypes/BuyXGetYTest.php @@ -4,6 +4,7 @@ use Lunar\DiscountTypes\AmountOff; use Lunar\DiscountTypes\BuyXGetY; use Lunar\Models\Cart; +use Lunar\Models\CartLine; use Lunar\Models\Channel; use Lunar\Models\Collection; use Lunar\Models\Currency; @@ -1640,3 +1641,97 @@ $this->assertEquals(1200, $cart->total->value); $this->assertCount(1, $cart->freeItems); }); + +test('can store an automatically added reward line using the morph map', function () { + $customerGroup = CustomerGroup::factory()->create([ + 'default' => true, + ]); + + $channel = Channel::factory()->create([ + 'default' => true, + ]); + + $currency = Currency::factory()->create([ + 'code' => 'GBP', + ]); + + $cart = Cart::factory()->create([ + 'channel_id' => $channel->id, + 'currency_id' => $currency->id, + ]); + + $productA = Product::factory()->create(); + $productB = Product::factory()->create(); + + $purchasableA = ProductVariant::factory()->create([ + 'product_id' => $productA->id, + ]); + $purchasableB = ProductVariant::factory()->create([ + 'product_id' => $productB->id, + ]); + + Price::factory()->create([ + 'price' => 1000, // £10 + 'min_quantity' => 1, + 'currency_id' => $currency->id, + 'priceable_type' => $purchasableA->getMorphClass(), + 'priceable_id' => $purchasableA->id, + ]); + + Price::factory()->create([ + 'price' => 1000, // £10 + 'min_quantity' => 1, + 'currency_id' => $currency->id, + 'priceable_type' => $purchasableB->getMorphClass(), + 'priceable_id' => $purchasableB->id, + ]); + + $cart->lines()->create([ + 'purchasable_type' => $purchasableA->getMorphClass(), + 'purchasable_id' => $purchasableA->id, + 'quantity' => 1, + ]); + + $discount = Discount::factory()->create([ + 'type' => BuyXGetY::class, + 'name' => 'Test Product Discount', + 'data' => [ + 'min_qty' => 1, + 'reward_qty' => 1, + 'automatically_add_rewards' => true, + ], + ]); + + $discount->customerGroups()->sync([ + $customerGroup->id => [ + 'enabled' => true, + 'starts_at' => now(), + ], + ]); + + $discount->channels()->sync([ + $channel->id => [ + 'enabled' => true, + 'starts_at' => now()->subHour(), + ], + ]); + + $discount->discountableConditions()->create([ + 'discountable_type' => $productA->getMorphClass(), + 'discountable_id' => $productA->id, + ]); + + $discount->discountableRewards()->create([ + 'discountable_type' => $productB->getMorphClass(), + 'discountable_id' => $productB->id, + 'type' => 'reward', + ]); + + $cart->calculate(); + + $rewardLine = CartLine::where('cart_id', $cart->id) + ->where('purchasable_id', $purchasableB->id) + ->first(); + + expect($rewardLine->purchasable_type)->toEqual($purchasableB->getMorphClass()); +});