diff --git a/config/balance.php b/config/balance.php index a06c470..c86f88e 100644 --- a/config/balance.php +++ b/config/balance.php @@ -1,9 +1,17 @@ 'balances' + 'table' => 'balances', + + /** + * Default model to use. + * Change this if you have extended the model. + */ + 'model' => Balance::class, ]; diff --git a/src/Concerns/BalanceInterface.php b/src/Concerns/BalanceInterface.php new file mode 100644 index 0000000..654de07 --- /dev/null +++ b/src/Concerns/BalanceInterface.php @@ -0,0 +1,12 @@ +morphMany(Balance::class, 'balanceable'); + return $this->morphMany(config('balance.model'), 'balanceable'); } public function withCurrency(string $currency): self @@ -37,17 +38,17 @@ protected function creditCurrency(): Attribute ); } - public function increaseCredit(int $amount, ?string $reason = null): Balance + public function increaseCredit(int $amount, ?string $reason = null): BalanceInterface { return $this->createCredit($amount, $reason); } - public function decreaseCredit(int $amount, ?string $reason = null): Balance + public function decreaseCredit(int $amount, ?string $reason = null): BalanceInterface { return $this->createCredit(-1 * abs($amount), $reason); } - public function setCredit(int $amount, ?string $reason = null): Balance + public function setCredit(int $amount, ?string $reason = null): BalanceInterface { return $this->createCredit($amount, $reason); } @@ -62,7 +63,7 @@ public function hasCredit(): bool return $this->credit > 0; } - protected function createCredit(int $amount, ?string $reason = null): Balance + protected function createCredit(int $amount, ?string $reason = null): Model|BalanceInterface { return $this->credits()->create([ 'amount' => $amount, diff --git a/tests/ExampleTest.php b/tests/ExampleTest.php index 5d36321..f4fdff6 100644 --- a/tests/ExampleTest.php +++ b/tests/ExampleTest.php @@ -1,5 +1,85 @@ toBeTrue(); }); + +it ('can use any model configured in the config balance.model and implements the BalanceInterface', function () { + config()->set('database.default', 'testing'); + + // Run the test user migration + $migration = include __DIR__.'/create_test_user_table.php.stub'; + $migration->up(); + + // Run the balance migration + $migration = include __DIR__.'/create_balances_custom_table.php.stub'; + $migration->up(); + + config()->set('balance.table', 'balances_custom'); + config()->set('balance.model', CustomBalance::class); + + $user = User::create([ + 'name' => 'John Doe', + 'email' => 'john@doe.com', + ]); + $user->setCredit(2000); + $this->assertEquals(2000, $user->credit); + $user->increaseCredit(1000); + $this->assertEquals(3000, $user->credit); + $user->decreaseCredit(500); + $this->assertEquals(2500, $user->credit); + + $this->assertEquals('$25.00', $user->creditCurrency); +}); + + +// Create a model that uses the HasBalance trait and test that it can increase, decrease, set and reset the balance +class User extends Model +{ + use HasBalance; + + protected $fillable = ['name', 'email']; +} + + +class CustomBalance extends Model implements BalanceInterface +{ + protected $guarded = []; + + // before saving the model ensure the custom column is the name of the model that originated the balance + protected static function boot() + { + parent::boot(); + + static::saving(function ($model) { + $model->custom = get_class($model->balanceable); + }); + } + + public function __construct(array $attributes = []) + { + parent::__construct($attributes); + + $this->guarded[] = $this->primaryKey; + $this->table = config('balance.table'); + } + + protected function amountCurrency(): Attribute + { + return Attribute::make( + get: fn () => Number::currency($this->amount / 100), + ); + } + + public function balanceable(): MorphTo + { + return $this->morphTo(); + } +} diff --git a/tests/create_balances_custom_table.php.stub b/tests/create_balances_custom_table.php.stub new file mode 100644 index 0000000..3594495 --- /dev/null +++ b/tests/create_balances_custom_table.php.stub @@ -0,0 +1,20 @@ +id(); + $table->morphs('balanceable'); + $table->integer('amount'); + $table->text('reason')->nullable(); + $table->text('custom')->nullable(); + $table->timestamps(); + }); + } +}; diff --git a/tests/create_test_user_table.php.stub b/tests/create_test_user_table.php.stub new file mode 100644 index 0000000..27e6089 --- /dev/null +++ b/tests/create_test_user_table.php.stub @@ -0,0 +1,23 @@ +id(); + $table->string('name'); + $table->string('email')->unique(); + $table->timestamps(); + }); + } +};