diff --git a/src/app/Console/Commands/Wallet/ChargeCommand.php b/src/app/Console/Commands/Wallet/ChargeCommand.php --- a/src/app/Console/Commands/Wallet/ChargeCommand.php +++ b/src/app/Console/Commands/Wallet/ChargeCommand.php @@ -44,7 +44,7 @@ $wallets = [$wallet]; } else { // Get all wallets, excluding deleted accounts - $wallets = \App\Wallet::select('wallets.*') + $wallets = \App\Wallet::select('wallets.id') ->join('users', 'users.id', '=', 'wallets.user_id') ->withEnvTenantContext('users') ->whereNull('users.deleted_at') @@ -52,6 +52,16 @@ } foreach ($wallets as $wallet) { + // This is a long-running process. Because another process might have modified + // the wallet balance in meantime we have to refresh it. + // Note: This is needed despite the use of cursor() above. + $wallet->refresh(); + + // Sanity check after refresh (owner deleted in meantime) + if (!$wallet->owner) { + continue; + } + $charge = $wallet->chargeEntitlements(); if ($charge > 0) { diff --git a/src/app/Providers/PaymentProvider.php b/src/app/Providers/PaymentProvider.php --- a/src/app/Providers/PaymentProvider.php +++ b/src/app/Providers/PaymentProvider.php @@ -303,7 +303,7 @@ } $methods = self::applyMethodWhitelist($type, $methods); - \Log::debug("Loaded payment methods" . var_export($methods, true)); + \Log::debug("Loaded payment methods " . var_export($methods, true)); Cache::put($cacheKey, $methods, now()->addHours(1)); diff --git a/src/tests/Feature/WalletTest.php b/src/tests/Feature/WalletTest.php --- a/src/tests/Feature/WalletTest.php +++ b/src/tests/Feature/WalletTest.php @@ -599,7 +599,28 @@ */ public function testAwardAndPenalty(): void { - $this->markTestIncomplete(); + $user = $this->getTestUser('UserWallet1@UserWallet.com'); + $wallet = $user->wallets()->first(); + + // Test award + $this->assertSame($wallet->id, $wallet->award(100, 'test')->id); + $this->assertSame(100, $wallet->balance); + $this->assertSame(100, $wallet->fresh()->balance); + $transaction = $wallet->transactions()->first(); + $this->assertSame(100, $transaction->amount); + $this->assertSame(Transaction::WALLET_AWARD, $transaction->type); + $this->assertSame('test', $transaction->description); + + $wallet->transactions()->delete(); + + // Test penalty + $this->assertSame($wallet->id, $wallet->penalty(100, 'test')->id); + $this->assertSame(0, $wallet->balance); + $this->assertSame(0, $wallet->fresh()->balance); + $transaction = $wallet->transactions()->first(); + $this->assertSame(-100, $transaction->amount); + $this->assertSame(Transaction::WALLET_PENALTY, $transaction->type); + $this->assertSame('test', $transaction->description); } /**