diff --git a/database/factories/TransactionEventFactory.php b/database/factories/TransactionEventFactory.php index c968f61..a4e2ad2 100644 --- a/database/factories/TransactionEventFactory.php +++ b/database/factories/TransactionEventFactory.php @@ -8,6 +8,7 @@ use Payavel\Checkout\CheckoutStatus; use Payavel\Checkout\Models\Dispute; use Payavel\Checkout\Models\Refund; +use Payavel\Orchestration\Support\ServiceConfig; class TransactionEventFactory extends Factory { @@ -37,26 +38,26 @@ public function definition() */ public function configure() { + $this->model = ServiceConfig::get('checkout', 'models.' . $this->model, $this->model); + return $this->afterMaking(function (TransactionEvent $transactionEvent) { if (is_null($transactionEvent->payment_id)) { $transactionEvent->payment_id = Payment::factory()->create()->id; } - if (is_null($transactionEvent->transactionable_id)) { - $transactionEvent->transactionable_id = $transactionEvent->payment_id; - $transactionEvent->transactionable_type = Payment::class; - } - if (is_null($transactionEvent->amount)) { - $transactionEvent->amount = $transactionEvent->transactionable->amount; + $transactionEvent->amount = $transactionEvent->transactionable->amount ?? $transactionEvent->payment->amount; } if (is_null($transactionEvent->status_code)) { $transactionEvent->status_code = [ - Payment::class => CheckoutStatus::AUTHORIZED, - Refund::class => CheckoutStatus::REFUNDED, - Dispute::class => CheckoutStatus::CHARGEBACK, - ][$transactionEvent->transactionable_type]; + ServiceConfig::get('checkout', 'models.' . Payment::class, Payment::class) => CheckoutStatus::AUTHORIZED, + ServiceConfig::get('checkout', 'models.' . Refund::class, Refund::class) => CheckoutStatus::REFUNDED, + ServiceConfig::get('checkout', 'models.' . Dispute::class, Dispute::class) => CheckoutStatus::CHARGEBACK, + ][ + ServiceConfig::get('checkout', 'models.' . $transactionEvent->transactionable_type, $transactionEvent->transactionable_type) ?? + ServiceConfig::get('checkout', 'models.' . Payment::class, Payment::class) + ]; } }); } diff --git a/database/migrations/2024_01_01_000010_create_base_checkout_tables.php b/database/migrations/2024_01_01_000010_create_base_checkout_tables.php index e6737d9..f1b5088 100644 --- a/database/migrations/2024_01_01_000010_create_base_checkout_tables.php +++ b/database/migrations/2024_01_01_000010_create_base_checkout_tables.php @@ -112,7 +112,7 @@ public function up() Schema::create('transaction_events', function (Blueprint $table) { $table->bigIncrements('id'); $table->unsignedBigInteger('payment_id'); - $table->morphs('transactionable'); + $table->nullableMorphs('transactionable'); $table->string('reference'); $table->unsignedInteger('status_code'); $table->unsignedInteger('amount'); diff --git a/src/CheckoutServiceProvider.php b/src/CheckoutServiceProvider.php index 193516e..9daa762 100644 --- a/src/CheckoutServiceProvider.php +++ b/src/CheckoutServiceProvider.php @@ -2,9 +2,14 @@ namespace Payavel\Checkout; +use Illuminate\Database\Eloquent\Relations\Relation; use Illuminate\Support\ServiceProvider; use Payavel\Checkout\Console\Commands\CheckoutInstall; use Payavel\Checkout\Console\Commands\CheckoutProvider; +use Payavel\Checkout\Models\Dispute; +use Payavel\Checkout\Models\Payment; +use Payavel\Checkout\Models\Refund; +use Payavel\Orchestration\Support\ServiceConfig; class CheckoutServiceProvider extends ServiceProvider { @@ -19,6 +24,12 @@ public function boot() $this->registerCommands(); $this->registerMigrations(); + + Relation::morphMap([ + Payment::class => fn () => ServiceConfig::get('checkout', 'models.' . Payment::class, Payment::class), + Refund::class => fn () => ServiceConfig::get('checkout', 'models.' . Refund::class, Refund::class), + Dispute::class => fn () => ServiceConfig::get('checkout', 'models.' . Dispute::class, Dispute::class), + ]); } public function register() diff --git a/tests/Models/TestDispute.php b/tests/Models/TestDispute.php new file mode 100644 index 0000000..c16fd5f --- /dev/null +++ b/tests/Models/TestDispute.php @@ -0,0 +1,22 @@ +create(); + $this->assertInstanceOf(Payment::class, $transactionEventWithPayment->payment); + + ServiceConfig::set('checkout', 'models.' . Payment::class, TestPayment::class); + $transactionEventWithOverriddenPayment = TransactionEvent::factory()->create(); + $this->assertInstanceOf(TestPayment::class, $transactionEventWithOverriddenPayment->payment); + } + + #[Test] + public function retrieve_transaction_event_transactionable() + { + $transactionEvent = TransactionEvent::factory()->create(); + $this->assertNull($transactionEvent->transactionable); + + $transactionables = [ + Payment::class => TestPayment::class, + Refund::class => TestRefund::class, + Dispute::class => TestDispute::class, + ]; + + $randomTransactionable = $this->faker->randomElement(array_keys($transactionables)); + $transactionEventWithTransactionable = TransactionEvent::factory()->for($randomTransactionable::factory(), 'transactionable')->create(); + $this->assertInstanceOf($randomTransactionable, $transactionEventWithTransactionable->transactionable); + + $randomTransactionable = $this->faker->randomElement(array_keys($transactionables)); + ServiceConfig::set('checkout', 'models.' . $randomTransactionable, $transactionables[$randomTransactionable]); + $transactionEventWithOverriddenTransactionable = TransactionEvent::factory()->for($transactionables[$randomTransactionable]::factory(), 'transactionable')->create(); + $this->assertInstanceOf($transactionables[$randomTransactionable], $transactionEventWithOverriddenTransactionable->transactionable); + } +}