Skip to content

Commit

Permalink
Added PromotionAction and CartFixedDiscount action type
Browse files Browse the repository at this point in the history
  • Loading branch information
kedves committed Jul 12, 2024
1 parent d222bbd commit 99bb8ac
Show file tree
Hide file tree
Showing 12 changed files with 280 additions and 4 deletions.
64 changes: 64 additions & 0 deletions src/Promotion/Actions/CartFixedDiscount.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

declare(strict_types=1);

namespace Vanilo\Promotion\Actions;

use Nette\Schema\Expect;
use Nette\Schema\Processor;
use Nette\Schema\Schema;
use Vanilo\Adjustments\Adjusters\SimpleDiscount;
use Vanilo\Adjustments\Contracts\Adjuster;
use Vanilo\Cart\Contracts\Cart;
use Vanilo\Promotion\Contracts\PromotionActionType;

class CartFixedDiscount implements PromotionActionType
{
private ?array $configuration = null;

public static function getName(): string
{
return __('Cart fixed discount');
}

public static function getID(): string
{
return 'cart_fixed_discount';
}

public function adjust(object $subject): Adjuster
{
if (!$subject instanceof Cart) {
throw new \InvalidArgumentException('Subject must be an instance of '.Cart::class);
}

return new SimpleDiscount($this->getConfiguration()['discount_amount'] / 100 * $subject->total());
}

public function getSchema(): ?Schema
{
return Expect::structure(['discount_amount' => Expect::int(0)->required()]);
}

public function setConfiguration(array $configuration): self
{
if ($this->getSchema()) {
$configuration = (new Processor())->process($this->getSchema(), $configuration);
}

$this->configuration = (array)$configuration;

return $this;
}

public function getConfiguration(): ?array
{
$configuration = $this->configuration;

if ($this->getSchema()) {
$configuration = (new Processor())->process($this->getSchema(), $configuration);
}

return (array)$configuration;
}
}
15 changes: 15 additions & 0 deletions src/Promotion/Contracts/PromotionAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace Vanilo\Promotion\Contracts;

use Vanilo\Adjustments\Contracts\Adjustable;
use Vanilo\Contracts\Configurable;

interface PromotionAction extends Configurable
{
public function getActionType(): PromotionActionType;

public function executeActionType(object $subject): Adjustable;
}
23 changes: 23 additions & 0 deletions src/Promotion/Contracts/PromotionActionType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace Vanilo\Promotion\Contracts;

use Nette\Schema\Schema;
use Vanilo\Adjustments\Contracts\Adjuster;

interface PromotionActionType
{
public static function getName(): string;

public static function getID(): string;

public function adjust(object $subject): Adjuster;

public function getSchema(): ?Schema;

public function setConfiguration(array $configuration): self;

public function getConfiguration(): ?array;
}
11 changes: 11 additions & 0 deletions src/Promotion/Exceptions/InexistentPromotionActionException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

namespace Vanilo\Promotion\Exceptions;

use RuntimeException;

class InexistentPromotionActionException extends RuntimeException
{
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@

use RuntimeException;

class InexistentRuleException extends RuntimeException
class InexistentPromotionRuleException extends RuntimeException
{
}
51 changes: 51 additions & 0 deletions src/Promotion/Models/PromotionAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

namespace Vanilo\Promotion\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Vanilo\Adjustments\Contracts\Adjustable;
use Vanilo\Promotion\Contracts\Promotion;
use Vanilo\Promotion\Contracts\PromotionAction as PromotionActionContract;
use Vanilo\Promotion\Contracts\PromotionActionType;
use Vanilo\Promotion\Contracts\PromotionRuleType;
use Vanilo\Promotion\PromotionRuleTypes;
use Vanilo\Support\Traits\ConfigurableModel;
use Vanilo\Support\Traits\ConfigurationHasNoSchema;

/**
* @property int $id
* @property int $promotion_id
* @property string $type
* @property ?array $configuration
*
* @property Promotion $promotion
*/
class PromotionAction extends Model implements PromotionActionContract
{
use ConfigurableModel;
use ConfigurationHasNoSchema;

protected $guarded = ['id', 'created_at', 'updated_at'];

protected $casts = [
'configuration' => 'array',
];

public function promotion(): BelongsTo
{
return $this->belongsTo(PromotionProxy::modelClass());
}

public function getActionType(): PromotionActionType
{
// TODO: Implement getActionType() method.
}

public function executeActionType(object $subject): Adjustable
{
// TODO: Implement executeActionType() method.
}
}
11 changes: 11 additions & 0 deletions src/Promotion/Models/PromotionActionProxy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

namespace Vanilo\Promotion\Models;

use Konekt\Concord\Proxies\ModelProxy;

class PromotionActionProxy extends ModelProxy
{
}
72 changes: 72 additions & 0 deletions src/Promotion/PromotionActionTypes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

declare(strict_types=1);

namespace Vanilo\Promotion;

use Vanilo\Promotion\Contracts\PromotionActionType;
use Vanilo\Promotion\Exceptions\InexistentPromotionActionException;

final class PromotionActionTypes
{
private static array $registry = [];

public static function register(string $id, string $class)
{
if (array_key_exists($id, self::$registry)) {
return;
}

if (!in_array(PromotionActionType::class, class_implements($class))) {
throw new \InvalidArgumentException(
sprintf(
'The class you are trying to register (%s) as promotion action, ' .
'must implement the %s interface.',
$class,
PromotionActionType::class
)
);
}

self::$registry[$id] = $class;
}

public static function make(string $id): PromotionActionType
{
$gwClass = self::getClass($id);

if (null === $gwClass) {
throw new InexistentPromotionActionException(
"No action is registered with the id `$id`."
);
}

return app()->make($gwClass);
}

public static function reset(): void
{
self::$registry = [];
}

public static function getClass(string $id): ?string
{
return self::$registry[$id] ?? null;
}

public static function ids(): array
{
return array_keys(self::$registry);
}

public static function choices(): array
{
$result = [];

foreach (self::$registry as $type => $class) {
$result[$type] = $class::getName();
}

return $result;
}
}
4 changes: 2 additions & 2 deletions src/Promotion/PromotionRuleTypes.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Vanilo\Promotion;

use Vanilo\Promotion\Contracts\PromotionRuleType;
use Vanilo\Promotion\Exceptions\InexistentRuleException;
use Vanilo\Promotion\Exceptions\InexistentPromotionRuleException;

final class PromotionRuleTypes
{
Expand Down Expand Up @@ -36,7 +36,7 @@ public static function make(string $id): PromotionRuleType
$gwClass = self::getClass($id);

if (null === $gwClass) {
throw new InexistentRuleException(
throw new InexistentPromotionRuleException(
"No rule is registered with the id `$id`."
);
}
Expand Down
2 changes: 2 additions & 0 deletions src/Promotion/Providers/ModuleServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Konekt\Concord\BaseModuleServiceProvider;
use Vanilo\Promotion\Models\Coupon;
use Vanilo\Promotion\Models\Promotion;
use Vanilo\Promotion\Models\PromotionAction;
use Vanilo\Promotion\Models\PromotionRule;
use Vanilo\Promotion\PromotionRuleTypes;
use Vanilo\Promotion\Rules\CartQuantity;
Expand All @@ -17,6 +18,7 @@ class ModuleServiceProvider extends BaseModuleServiceProvider
Promotion::class,
Coupon::class,
PromotionRule::class,
PromotionAction::class,
];

public function boot()
Expand Down
3 changes: 2 additions & 1 deletion src/Promotion/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
"php": "^8.2",
"konekt/concord": "^1.13",
"laravel/framework": "^10.43|^11.0",
"vanilo/support": "^4.0"
"vanilo/support": "^4.0",
"vanilo/adjustments": "^4.0"
},
"require-dev": {
"phpunit/phpunit": "^10.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class () extends Migration {
public function up(): void
{
Schema::create('promotion_actions', function (Blueprint $table) {
$table->id();
$table->unsignedInteger('promotion_id');
$table->string('type');
$table->json('configuration')->nullable();
$table->timestamps();
$table->foreign('promotion_id')->references('id')->on('promotions');
});
}

public function down(): void
{
Schema::drop('promotion_actions');
}
};

0 comments on commit 99bb8ac

Please sign in to comment.