Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/Models/Product.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Rapidez\Core\Facades\Rapidez;
use Rapidez\Core\Models\Relations\BelongsToManyCallback;
Expand Down Expand Up @@ -241,7 +242,9 @@ public function getUnitPrice(int $quantity = 1, int $customerGroup = 0)
// NOTE: We always need the option with the lowest matching value, *not* the one with the highest matching qty!
// It wouldn't make sense to select a tier with a higher qty if the price is higher.

return $tierPrice ?? $this->price;
$prices = Arr::whereNotNull([$tierPrice, $this->price, $this->specialPrice]);

return $prices ? min($prices) : null;
}

public function getPrice(int $quantity = 1, int $customerGroup = 0)
Expand Down
2 changes: 2 additions & 0 deletions src/Models/ProductTierPrice.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ class ProductTierPrice extends Model

protected $primaryKey = 'value_id';

protected $guarded = [];

public function product(): BelongsTo
{
return $this->belongsTo(
Expand Down
48 changes: 46 additions & 2 deletions tests/Unit/ProductPriceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,51 @@ public function product_catalog_price_rules_apply()
#[Test]
public function product_can_have_tier_prices()
{
$this->assertTrue(true);
// TODO: Base DB doesn't have tier prices. Test this some other way.
$product = Product::find(4);

$product->tierPrices()->create(['qty' => 2, 'value' => 50, 'website_id' => 1, 'all_groups' => 1, 'customer_group_id' => 0]);
$product->tierPrices()->create(['qty' => 5, 'value' => 40, 'website_id' => 1, 'all_groups' => 1, 'customer_group_id' => 0]);
$product->tierPrices()->create(['qty' => 10, 'value' => 35, 'website_id' => 1, 'all_groups' => 1, 'customer_group_id' => 0]);
$product->tierPrices()->create(['qty' => 15, 'value' => 40, 'website_id' => 1, 'all_groups' => 1, 'customer_group_id' => 0]);

$product->tierPrices()->create(['qty' => 1, 'value' => 43, 'website_id' => 1, 'all_groups' => 0, 'customer_group_id' => 2]);
$product->tierPrices()->create(['qty' => 5, 'value' => 39, 'website_id' => 1, 'all_groups' => 0, 'customer_group_id' => 2]);
$product->tierPrices()->create(['qty' => 15, 'value' => 34, 'website_id' => 1, 'all_groups' => 0, 'customer_group_id' => 2]);

$product->tierPrices()->create(['qty' => 20, 'value' => 30, 'website_id' => 0, 'all_groups' => 1, 'customer_group_id' => 0]);

// All groups
$this->assertEquals(45 * 4, $product->getPrice(4), 'Tier price for all groups, qty 4');
$this->assertEquals(40 * 5, $product->getPrice(5), 'Tier price for all groups, qty 5');
$this->assertEquals(35 * 12, $product->getPrice(12), 'Tier price for all groups, qty 12');
$this->assertEquals(35 * 15, $product->getPrice(15), 'Tier price for all groups, qty 15');
$this->assertEquals(30 * 23, $product->getPrice(23), 'Tier price for all groups, qty 23');

// Specifically customer group 2
$this->assertEquals(43 * 4, $product->getPrice(4, 2), 'Tier price for group 2, qty 4');
$this->assertEquals(39 * 5, $product->getPrice(5, 2), 'Tier price for group 2, qty 5');
$this->assertEquals(35 * 12, $product->getPrice(12, 2), 'Tier price for group 2, qty 12');
$this->assertEquals(34 * 15, $product->getPrice(15, 2), 'Tier price for group 2, qty 15');
$this->assertEquals(30 * 22, $product->getPrice(22, 2), 'Tier price for group 2, qty 22');

// This is technically not valid, but without creating a whole new website this is the best we can do in a unit test.
config()->set('rapidez.website', 0);
$this->assertEquals(45 * 15, $product->getPrice(15, 2), 'Tier price on website 0 for group 2, qty 15');
$this->assertEquals(45 * 15, $product->getPrice(15), 'Tier price on website 0 for all groups, qty 15');
$this->assertEquals(30 * 21, $product->getPrice(21), 'Tier price on website 0 for all groups, qty 21');
}

#[Test]
public function product_can_combine_tier_prices_and_special_price()
{
$product = Product::find(10);

$product->tierPrices()->create(['qty' => 5, 'value' => 30, 'website_id' => 1, 'all_groups' => 1, 'customer_group_id' => 0]);
$product->tierPrices()->create(['qty' => 10, 'value' => 20, 'website_id' => 1, 'all_groups' => 1, 'customer_group_id' => 0]);

// All groups
$this->assertEquals(24 * 4, $product->getPrice(4), 'Tier price (should be special price) for all groups, qty 4');
$this->assertEquals(24 * 5, $product->getPrice(5), 'Tier price (should be special price) for all groups, qty 5');
$this->assertEquals(20 * 12, $product->getPrice(12), 'Tier price for all groups, qty 12');
}
}
Loading