-
-
Notifications
You must be signed in to change notification settings - Fork 235
Commit
[11.x] add native soft delete
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
use Bavix\Wallet\Models\Transaction; | ||
use Bavix\Wallet\Models\Transfer; | ||
use Bavix\Wallet\Models\Wallet; | ||
use Illuminate\Database\Migrations\Migration; | ||
Check warning on line 8 in database/2023_12_30_204610_soft_delete.php GitHub Actions / Qodana for PHPUndefined class
|
||
use Illuminate\Database\Schema\Blueprint; | ||
Check warning on line 9 in database/2023_12_30_204610_soft_delete.php GitHub Actions / Qodana for PHPUndefined class
|
||
use Illuminate\Support\Facades\Schema; | ||
Check warning on line 10 in database/2023_12_30_204610_soft_delete.php GitHub Actions / Qodana for PHPUndefined class
|
||
|
||
return new class() extends Migration { | ||
public function up(): void | ||
{ | ||
Schema::table((new Wallet())->getTable(), static function (Blueprint $table) { | ||
Check warning on line 15 in database/2023_12_30_204610_soft_delete.php GitHub Actions / Qodana for PHPUndefined class
|
||
$table->dropUnique(['holder_type', 'holder_id', 'slug']); | ||
|
||
$table->softDeletesTz(); | ||
|
||
$table->unique(['holder_type', 'holder_id', 'slug', 'deleted_at']); | ||
}); | ||
Schema::table((new Transfer())->getTable(), static function (Blueprint $table) { | ||
Check warning on line 22 in database/2023_12_30_204610_soft_delete.php GitHub Actions / Qodana for PHPUndefined class
|
||
$table->softDeletesTz(); | ||
}); | ||
Schema::table((new Transaction())->getTable(), static function (Blueprint $table) { | ||
Check warning on line 25 in database/2023_12_30_204610_soft_delete.php GitHub Actions / Qodana for PHPUndefined class
|
||
$table->softDeletesTz(); | ||
}); | ||
} | ||
|
||
public function down(): void | ||
{ | ||
Schema::table((new Wallet())->getTable(), static function (Blueprint $table) { | ||
Check warning on line 32 in database/2023_12_30_204610_soft_delete.php GitHub Actions / Qodana for PHPUndefined class
|
||
$table->dropUnique(['holder_type', 'holder_id', 'slug', 'deleted_at']); | ||
$table->unique(['holder_type', 'holder_id', 'slug']); | ||
|
||
$table->dropSoftDeletes(); | ||
}); | ||
Schema::table((new Transfer())->getTable(), static function (Blueprint $table) { | ||
Check warning on line 38 in database/2023_12_30_204610_soft_delete.php GitHub Actions / Qodana for PHPUndefined class
|
||
$table->dropSoftDeletes(); | ||
}); | ||
Schema::table((new Transaction())->getTable(), static function (Blueprint $table) { | ||
Check warning on line 41 in database/2023_12_30_204610_soft_delete.php GitHub Actions / Qodana for PHPUndefined class
|
||
$table->dropSoftDeletes(); | ||
}); | ||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Bavix\Wallet\Internal\Observers; | ||
|
||
use Bavix\Wallet\Exceptions\UnconfirmedInvalid; | ||
use Bavix\Wallet\Exceptions\WalletOwnerInvalid; | ||
use Bavix\Wallet\Internal\Exceptions\ExceptionInterface; | ||
use Bavix\Wallet\Internal\Exceptions\RecordNotFoundException; | ||
use Bavix\Wallet\Internal\Exceptions\TransactionFailedException; | ||
use Bavix\Wallet\Models\Transaction; | ||
use Illuminate\Database\RecordsNotFoundException; | ||
Check warning on line 13 in src/Internal/Observers/TransactionObserver.php GitHub Actions / Qodana for PHPUndefined class
|
||
|
||
final class TransactionObserver | ||
{ | ||
/** | ||
* @throws UnconfirmedInvalid | ||
* @throws WalletOwnerInvalid | ||
* @throws RecordNotFoundException | ||
* @throws RecordsNotFoundException | ||
* @throws TransactionFailedException | ||
* @throws ExceptionInterface | ||
*/ | ||
public function deleting(Transaction $model): bool | ||
{ | ||
return $model->wallet->resetConfirm($model); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Bavix\Wallet\Internal\Observers; | ||
|
||
use Bavix\Wallet\Exceptions\UnconfirmedInvalid; | ||
use Bavix\Wallet\Exceptions\WalletOwnerInvalid; | ||
use Bavix\Wallet\Internal\Exceptions\ExceptionInterface; | ||
use Bavix\Wallet\Internal\Exceptions\RecordNotFoundException; | ||
use Bavix\Wallet\Internal\Exceptions\TransactionFailedException; | ||
use Bavix\Wallet\Models\Transfer; | ||
use Bavix\Wallet\Services\AtomicServiceInterface; | ||
use Illuminate\Database\RecordsNotFoundException; | ||
Check warning on line 14 in src/Internal/Observers/TransferObserver.php GitHub Actions / Qodana for PHPUndefined class
|
||
|
||
final class TransferObserver | ||
{ | ||
public function __construct( | ||
private readonly AtomicServiceInterface $atomicService | ||
) { | ||
} | ||
|
||
/** | ||
* @throws UnconfirmedInvalid | ||
* @throws WalletOwnerInvalid | ||
* @throws RecordNotFoundException | ||
* @throws RecordsNotFoundException | ||
* @throws TransactionFailedException | ||
* @throws ExceptionInterface | ||
*/ | ||
public function deleting(Transfer $model): bool | ||
{ | ||
return $this->atomicService->blocks([$model->from, $model->to], function () use ($model) { | ||
return $model->from->resetConfirm($model->withdraw) | ||
&& $model->to->resetConfirm($model->deposit); | ||
}); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Bavix\Wallet\Test\Units\Domain; | ||
|
||
use Bavix\Wallet\Test\Infra\Factories\BuyerFactory; | ||
use Bavix\Wallet\Test\Infra\Models\Buyer; | ||
use Bavix\Wallet\Test\Infra\TestCase; | ||
|
||
/** | ||
* @internal | ||
*/ | ||
final class SoftDeleteTest extends TestCase | ||
{ | ||
public function testDefaultWalletSoftDelete(): void | ||
{ | ||
/** @var Buyer $buyer */ | ||
$buyer = BuyerFactory::new()->create(); | ||
self::assertFalse($buyer->relationLoaded('wallet')); | ||
self::assertFalse($buyer->wallet->exists); | ||
|
||
$buyer->deposit(1); | ||
|
||
$oldWallet = $buyer->wallet; | ||
|
||
self::assertTrue($buyer->wallet->exists); | ||
self::assertTrue($buyer->wallet->delete()); | ||
self::assertNotNull($buyer->wallet->deleted_at); | ||
|
||
/** @var Buyer $buyer */ | ||
$buyer = Buyer::query()->find($buyer->getKey()); | ||
|
||
$buyer->deposit(2); | ||
|
||
self::assertNotSame($buyer->wallet->getKey(), $oldWallet->getKey()); | ||
|
||
self::assertSame(1, $oldWallet->balanceInt); | ||
self::assertSame(2, $buyer->balanceInt); | ||
} | ||
|
||
public function testTransactionDelete(): void | ||
{ | ||
/** @var Buyer $buyer */ | ||
$buyer = BuyerFactory::new()->create(); | ||
self::assertFalse($buyer->relationLoaded('wallet')); | ||
self::assertFalse($buyer->wallet->exists); | ||
|
||
$transaction = $buyer->deposit(1); | ||
|
||
self::assertTrue($buyer->wallet->exists); | ||
self::assertSame(1, $buyer->balanceInt); | ||
|
||
self::assertTrue($transaction->delete()); | ||
|
||
self::assertSame(0, $buyer->balanceInt); | ||
self::assertFalse($transaction->confirmed); | ||
} | ||
|
||
public function testTransferDelete(): void | ||
{ | ||
/** @var Buyer $user1 */ | ||
/** @var Buyer $user2 */ | ||
[$user1, $user2] = BuyerFactory::times(2)->create(); | ||
|
||
self::assertFalse($user1->relationLoaded('wallet')); | ||
self::assertFalse($user1->wallet->exists); | ||
|
||
self::assertFalse($user2->relationLoaded('wallet')); | ||
self::assertFalse($user2->wallet->exists); | ||
|
||
$transfer = $user1->forceTransfer($user2, 100); | ||
|
||
self::assertNotNull($transfer); | ||
self::assertSame(100, $transfer->deposit->amount); | ||
self::assertSame(-100, $transfer->withdraw->amount); | ||
|
||
self::assertSame(-100, $user1->balanceInt); | ||
self::assertSame(100, $user2->balanceInt); | ||
|
||
self::assertTrue($transfer->delete()); | ||
|
||
self::assertSame(0, $user1->balanceInt); | ||
self::assertSame(0, $user2->balanceInt); | ||
} | ||
} |