-
-
Notifications
You must be signed in to change notification settings - Fork 102
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added the
CartMinimumValue
promotion rule
- Loading branch information
1 parent
04475dd
commit c191588
Showing
6 changed files
with
256 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/** | ||
* Contains the CartMinimumValue rule class. | ||
* | ||
* @copyright Copyright (c) 2024 Vanilo UG | ||
* @author Attila Fulop | ||
* @license MIT | ||
* @since 2024-08-26 | ||
* | ||
*/ | ||
|
||
namespace Vanilo\Promotion\Rules; | ||
|
||
use Nette\Schema\Expect; | ||
use Nette\Schema\Processor; | ||
use Nette\Schema\Schema; | ||
use Vanilo\Promotion\Contracts\PromotionRuleType; | ||
|
||
class CartMinimumValue implements PromotionRuleType | ||
{ | ||
public const DEFAULT_ID = 'cart_minimum_value'; | ||
|
||
public static function getName(): string | ||
{ | ||
return __('Cart Minimum Value'); | ||
} | ||
|
||
public function getTitle(array $configuration): string | ||
{ | ||
if (null === $amount = $configuration['amount'] ?? null) { | ||
return __('At least X cart value [Invalid Configuration: The `:parameter` parameter is missing]', ['parameter' => 'amount']); | ||
} | ||
|
||
return __('At least :amount cart value', ['amount' => (int) $amount]); | ||
} | ||
|
||
public function getSchema(): Schema | ||
{ | ||
return Expect::structure(['amount' => Expect::anyOf(Expect::float(0), Expect::int(0))->required()])->castTo('array'); | ||
} | ||
|
||
public function getSchemaSample(array $mergeWith = null): array | ||
{ | ||
return ['amount' => 19.99]; | ||
} | ||
|
||
public function isPassing(object $subject, array $configuration): bool | ||
{ | ||
$amount = match (true) { | ||
method_exists($subject, 'preAdjustmentTotal') => $subject->preAdjustmentTotal(), | ||
method_exists($subject, 'itemsTotal') => $subject->itemsTotal(), | ||
default => throw new \InvalidArgumentException('The cart minimum value promotion rule requires either `preAdjustmentsTotal()` or `itemsTotal()` method on its subject'), | ||
}; | ||
|
||
$configuration = (new Processor())->process($this->getSchema(), $configuration); | ||
|
||
return $amount >= $configuration['amount']; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Vanilo\Promotion\Tests\Examples; | ||
|
||
|
||
use Illuminate\Contracts\Auth\Authenticatable; | ||
use Illuminate\Database\Eloquent\Relations\MorphMany; | ||
use Illuminate\Support\Collection; | ||
use Vanilo\Adjustments\Contracts\Adjustable; | ||
use Vanilo\Adjustments\Contracts\AdjustmentCollection; | ||
use Vanilo\Cart\Contracts\Cart; | ||
use Vanilo\Cart\Contracts\CartItem; | ||
use Vanilo\Contracts\Buyable; | ||
|
||
class DummyAdjustableCart implements Cart, Adjustable | ||
{ | ||
public function __construct( | ||
private float $preAdjustmentTotal | ||
) { | ||
} | ||
|
||
public function preAdjustmentTotal(): float | ||
{ | ||
return $this->preAdjustmentTotal; | ||
} | ||
|
||
public function invalidateAdjustments(): void | ||
{ | ||
// TODO: Implement invalidateAdjustments() method. | ||
} | ||
|
||
public function adjustments(): AdjustmentCollection | ||
{ | ||
// TODO: Implement adjustments() method. | ||
} | ||
|
||
public function adjustmentsRelation(): MorphMany | ||
{ | ||
// TODO: Implement adjustmentsRelation() method. | ||
} | ||
|
||
public function recalculateAdjustments(): void | ||
{ | ||
// TODO: Implement recalculateAdjustments() method. | ||
} | ||
|
||
public function addItem(Buyable $product, float|int $qty = 1, array $params = []): CartItem | ||
{ | ||
// TODO: Implement addItem() method. | ||
} | ||
|
||
public function removeItem(CartItem $item): void | ||
{ | ||
// TODO: Implement removeItem() method. | ||
} | ||
|
||
public function removeProduct(Buyable $product): void | ||
{ | ||
// TODO: Implement removeProduct() method. | ||
} | ||
|
||
public function clear(): void | ||
{ | ||
// TODO: Implement clear() method. | ||
} | ||
|
||
public function itemCount(): int | ||
{ | ||
// TODO: Implement itemCount() method. | ||
} | ||
|
||
public function getUser(): ?Authenticatable | ||
{ | ||
// TODO: Implement getUser() method. | ||
} | ||
|
||
public function setUser(int|Authenticatable|string|null $user): void | ||
{ | ||
// TODO: Implement setUser() method. | ||
} | ||
|
||
public function getItems(): Collection | ||
{ | ||
// TODO: Implement getItems() method. | ||
} | ||
|
||
public function itemsTotal(): float | ||
{ | ||
// TODO: Implement itemsTotal() method. | ||
} | ||
|
||
public function total(): float | ||
{ | ||
// TODO: Implement total() method. | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/** | ||
* Contains the CartMinimumValueTest class. | ||
* | ||
* @copyright Copyright (c) 2024 Vanilo UG | ||
* @author Attila Fulop | ||
* @license MIT | ||
* @since 2024-08-26 | ||
* | ||
*/ | ||
|
||
namespace Rules; | ||
|
||
use Nette\Schema\ValidationException; | ||
use Vanilo\Promotion\PromotionRuleTypes; | ||
use Vanilo\Promotion\Rules\CartMinimumValue; | ||
use Vanilo\Promotion\Tests\Examples\DummyAdjustableCart; | ||
use Vanilo\Promotion\Tests\Examples\DummyCart; | ||
use Vanilo\Promotion\Tests\TestCase; | ||
|
||
class CartMinimumValueTest extends TestCase | ||
{ | ||
/** @test */ | ||
public function it_can_be_created() | ||
{ | ||
$ruleType = PromotionRuleTypes::make(CartMinimumValue::DEFAULT_ID); | ||
|
||
$this->assertInstanceOf(CartMinimumValue::class, $ruleType); | ||
} | ||
|
||
/** @test */ | ||
public function it_throws_an_exception_if_the_configuration_is_empty() | ||
{ | ||
$this->expectException(ValidationException::class); | ||
$rule = PromotionRuleTypes::make(CartMinimumValue::DEFAULT_ID); | ||
|
||
$rule->isPassing(new DummyCart(), []); | ||
} | ||
|
||
/** @test */ | ||
public function it_passes_if_the_rule_is_valid_and_the_items_total_is_above_the_threshold() | ||
{ | ||
$rule = new CartMinimumValue(); | ||
|
||
$this->assertTrue($rule->isPassing(new DummyCart(1, 20), ['amount' => 19.99])); | ||
} | ||
|
||
/** @test */ | ||
public function it_passes_if_the_items_total_equals_the_threshold() | ||
{ | ||
$rule = new CartMinimumValue(); | ||
|
||
$this->assertTrue($rule->isPassing(new DummyCart(1, 19.99), ['amount' => 19.99])); | ||
} | ||
|
||
/** @test */ | ||
public function it_does_not_pass_if_the_items_total_is_below_the_threshold() | ||
{ | ||
$rule = new CartMinimumValue(); | ||
|
||
$this->assertFalse($rule->isPassing(new DummyCart(1, 19.98), ['amount' => 19.99])); | ||
} | ||
|
||
/** @test */ | ||
public function it_passes_if_the_pre_adjustment_total_is_above_the_threshold() | ||
{ | ||
$rule = new CartMinimumValue(); | ||
|
||
$this->assertTrue($rule->isPassing(new DummyAdjustableCart(20), ['amount' => 19.99])); | ||
} | ||
|
||
/** @test */ | ||
public function it_passes_if_the_pre_adjustment_total_equals_the_threshold() | ||
{ | ||
$rule = new CartMinimumValue(); | ||
|
||
$this->assertTrue($rule->isPassing(new DummyAdjustableCart(19.99), ['amount' => 19.99])); | ||
} | ||
|
||
/** @test */ | ||
public function it_does_not_pass_if_the_pre_adjustment_total_is_below_the_threshold() | ||
{ | ||
$rule = new CartMinimumValue(); | ||
|
||
$this->assertFalse($rule->isPassing(new DummyAdjustableCart(19.98), ['amount' => 19.99])); | ||
} | ||
} |