From c0f7b1dd978a6c659d0f5c917ac75bfbd09bd3e4 Mon Sep 17 00:00:00 2001 From: Maxim Babichev Date: Wed, 20 Apr 2022 22:39:33 +0300 Subject: [PATCH] Improved eager loading. Quick refund goods --- config/config.php | 2 ++ .../Repository/TransferRepository.php | 15 +++++++++++++ .../TransferRepositoryInterface.php | 5 +++++ src/Models/Transfer.php | 1 + src/Services/TransferService.php | 22 +++++++++++++++++++ src/Services/TransferServiceInterface.php | 13 +++++++++++ src/Traits/CartPay.php | 17 +++++--------- src/Traits/MorphOneWallet.php | 18 ++++++++++----- src/WalletServiceProvider.php | 3 +++ tests/Units/Domain/CartTest.php | 2 ++ tests/Units/Domain/EagerLoadingTest.php | 5 +++++ 11 files changed, 86 insertions(+), 17 deletions(-) create mode 100644 src/Services/TransferService.php create mode 100644 src/Services/TransferServiceInterface.php diff --git a/config/config.php b/config/config.php index 7cb2c53ed..341500b4c 100644 --- a/config/config.php +++ b/config/config.php @@ -43,6 +43,7 @@ use Bavix\Wallet\Services\PurchaseService; use Bavix\Wallet\Services\RegulatorService; use Bavix\Wallet\Services\TaxService; +use Bavix\Wallet\Services\TransferService; use Bavix\Wallet\Services\WalletService; return [ @@ -102,6 +103,7 @@ 'prepare' => PrepareService::class, 'purchase' => PurchaseService::class, 'tax' => TaxService::class, + 'transfer' => TransferService::class, 'wallet' => WalletService::class, ], diff --git a/src/Internal/Repository/TransferRepository.php b/src/Internal/Repository/TransferRepository.php index 5b9fd5cb4..61a123439 100644 --- a/src/Internal/Repository/TransferRepository.php +++ b/src/Internal/Repository/TransferRepository.php @@ -8,6 +8,7 @@ use Bavix\Wallet\Internal\Query\TransferQueryInterface; use Bavix\Wallet\Internal\Transform\TransferDtoTransformerInterface; use Bavix\Wallet\Models\Transfer; +use Illuminate\Support\Facades\DB; final class TransferRepository implements TransferRepositoryInterface { @@ -48,4 +49,18 @@ public function findBy(TransferQueryInterface $query): array ->all() ; } + + /** + * @param non-empty-array $ids + */ + public function updateStatusByIds(string $status, array $ids): int + { + return $this->transfer->newQuery() + ->whereKey($ids) + ->update([ + 'status' => $status, + 'status_last' => DB::raw('status'), + ]) + ; + } } diff --git a/src/Internal/Repository/TransferRepositoryInterface.php b/src/Internal/Repository/TransferRepositoryInterface.php index 50498b4e8..bc7207a69 100644 --- a/src/Internal/Repository/TransferRepositoryInterface.php +++ b/src/Internal/Repository/TransferRepositoryInterface.php @@ -21,4 +21,9 @@ public function insertOne(TransferDtoInterface $dto): Transfer; * @return Transfer[] */ public function findBy(TransferQueryInterface $query): array; + + /** + * @param non-empty-array $ids + */ + public function updateStatusByIds(string $status, array $ids): int; } diff --git a/src/Models/Transfer.php b/src/Models/Transfer.php index 39843ab54..fc9304a28 100644 --- a/src/Models/Transfer.php +++ b/src/Models/Transfer.php @@ -13,6 +13,7 @@ * Class Transfer. * * @property string $status + * @property string $status_last * @property string $discount * @property int $deposit_id * @property int $withdraw_id diff --git a/src/Services/TransferService.php b/src/Services/TransferService.php new file mode 100644 index 000000000..5864ccac5 --- /dev/null +++ b/src/Services/TransferService.php @@ -0,0 +1,22 @@ +repository->updateStatusByIds($status, $ids); + } +} diff --git a/src/Services/TransferServiceInterface.php b/src/Services/TransferServiceInterface.php new file mode 100644 index 000000000..abf01c7da --- /dev/null +++ b/src/Services/TransferServiceInterface.php @@ -0,0 +1,13 @@ +block($this, function () use ($cart, $force, $gifts) { - $results = []; $transfers = app(PurchaseServiceInterface::class)->already($this, $cart->getBasketDto(), $gifts); if (count($transfers) !== $cart->getBasketDto()->total()) { throw new ModelNotFoundException( @@ -186,9 +185,11 @@ public function refundCart(CartInterface $cart, bool $force = false, bool $gifts $index = 0; $objects = []; + $transferIds = []; $transfers = array_values($transfers); $prepareService = app(PrepareServiceInterface::class); foreach ($cart->getBasketDto()->cursor() as $product) { + $transferIds[] = $transfers[$index]->getKey(); $objects[] = $prepareService->transferLazy( $product, $transfers[$index]->withdraw->wallet, @@ -206,15 +207,9 @@ public function refundCart(CartInterface $cart, bool $force = false, bool $gifts app(CommonServiceLegacy::class)->applyTransfers($objects); - // fixme: one query update for - foreach ($transfers as $transfer) { - $results[] = $transfer->update([ - 'status' => Transfer::STATUS_REFUND, - 'status_last' => $transfer->status, - ]); - } - - return count(array_unique($results)) === 1; + return app(TransferServiceInterface::class) + ->updateStatusByIds(Transfer::STATUS_REFUND, $transferIds) + ; }); } diff --git a/src/Traits/MorphOneWallet.php b/src/Traits/MorphOneWallet.php index 4dbf2a5d0..c10d94c75 100644 --- a/src/Traits/MorphOneWallet.php +++ b/src/Traits/MorphOneWallet.php @@ -25,12 +25,18 @@ public function wallet(): MorphOne ->getHolder($this) ->morphOne(config('wallet.wallet.model', WalletModel::class), 'holder') ->where('slug', config('wallet.wallet.default.slug', 'default')) - ->withDefault(array_merge(config('wallet.wallet.creating', []), [ - 'name' => config('wallet.wallet.default.name', 'Default Wallet'), - 'slug' => config('wallet.wallet.default.slug', 'default'), - 'meta' => config('wallet.wallet.default.meta', []), - 'balance' => 0, - ])) + ->withDefault(static function (WalletModel $wallet, object $holder) { + $wallet->forceFill(array_merge(config('wallet.wallet.creating', []), [ + 'name' => config('wallet.wallet.default.name', 'Default Wallet'), + 'slug' => config('wallet.wallet.default.slug', 'default'), + 'meta' => config('wallet.wallet.default.meta', []), + 'balance' => 0, + ])); + + if (property_exists($holder, 'exists') && $holder->exists) { + $wallet->setRelation('holder', $holder); + } + }) ; } } diff --git a/src/WalletServiceProvider.php b/src/WalletServiceProvider.php index 903b07ce8..0ac542186 100644 --- a/src/WalletServiceProvider.php +++ b/src/WalletServiceProvider.php @@ -87,6 +87,8 @@ use Bavix\Wallet\Services\RegulatorServiceInterface; use Bavix\Wallet\Services\TaxService; use Bavix\Wallet\Services\TaxServiceInterface; +use Bavix\Wallet\Services\TransferService; +use Bavix\Wallet\Services\TransferServiceInterface; use Bavix\Wallet\Services\WalletService; use Bavix\Wallet\Services\WalletServiceInterface; use function config; @@ -199,6 +201,7 @@ private function services(array $configure, array $cache): void $this->app->singleton(PrepareServiceInterface::class, $configure['prepare'] ?? PrepareService::class); $this->app->singleton(PurchaseServiceInterface::class, $configure['purchase'] ?? PurchaseService::class); $this->app->singleton(TaxServiceInterface::class, $configure['tax'] ?? TaxService::class); + $this->app->singleton(TransferServiceInterface::class, $configure['transfer'] ?? TransferService::class); $this->app->singleton(WalletServiceInterface::class, $configure['wallet'] ?? WalletService::class); $this->app->singleton(BookkeeperServiceInterface::class, fn () => $this->app->make( diff --git a/tests/Units/Domain/CartTest.php b/tests/Units/Domain/CartTest.php index fde6d948d..3647b8979 100644 --- a/tests/Units/Domain/CartTest.php +++ b/tests/Units/Domain/CartTest.php @@ -133,6 +133,7 @@ public function testPay(): void foreach ($transfers as $transfer) { self::assertSame(Transfer::STATUS_PAID, $transfer->status); + self::assertNull($transfer->status_last); } foreach ($cart->getItems() as $product) { @@ -143,6 +144,7 @@ public function testPay(): void foreach ($transfers as $transfer) { $transfer->refresh(); self::assertSame(Transfer::STATUS_REFUND, $transfer->status); + self::assertSame(Transfer::STATUS_PAID, $transfer->status_last); } } diff --git a/tests/Units/Domain/EagerLoadingTest.php b/tests/Units/Domain/EagerLoadingTest.php index 9fa3868b3..c75693392 100644 --- a/tests/Units/Domain/EagerLoadingTest.php +++ b/tests/Units/Domain/EagerLoadingTest.php @@ -21,6 +21,7 @@ public function testUuidDuplicate(): void /** @var Buyer[]|Collection $buyerTimes */ $buyerTimes = BuyerFactory::times(10)->create(); foreach ($buyerTimes as $buyerTime) { + self::assertTrue($buyerTime->wallet->relationLoaded('holder')); $buyerTime->deposit(100); } @@ -34,6 +35,8 @@ public function testUuidDuplicate(): void $balances = []; foreach ($buyers as $buyer) { self::assertTrue($buyer->relationLoaded('wallet')); + // self::assertTrue($buyer->wallet->relationLoaded('holder')); + // fixme: I did not find a way to load the buyer, maybe someday I will get there. $uuids[] = $buyer->wallet->uuid; $balances[] = $buyer->wallet->balanceInt; @@ -74,5 +77,7 @@ public function testMultiWallets(): void self::assertTrue($user->relationLoaded('wallets')); self::assertNotNull($user->getWallet('hello')); self::assertNotNull($user->getWallet('world')); + self::assertTrue($user->getWallet('hello')->relationLoaded('holder')); + self::assertSame($user, $user->getWallet('hello')->holder); } }