fix transaction bug
This commit is contained in:
@@ -2,10 +2,9 @@
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Price;
|
||||
use App\Models\Product;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Rooyesh\Wallet\models\Wallet;
|
||||
|
||||
/**
|
||||
@@ -77,6 +76,97 @@ class WalletBalanceService
|
||||
return round($mainGold + $orphanedGold, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* موجودی ریالی مؤثر کیف اصلی =
|
||||
* cash کیف اصلی + cash کیفهای legacy محصولات main_wallet_products.
|
||||
*/
|
||||
public function effectiveMainWalletCash(int $ownerId, ?int $ownerType = null): float
|
||||
{
|
||||
$mainQuery = Wallet::query()
|
||||
->where('owner', $ownerId)
|
||||
->whereNull('fund_id')
|
||||
->whereNull('product_id');
|
||||
if ($ownerType !== null) {
|
||||
$mainQuery->where('owner_type', $ownerType);
|
||||
}
|
||||
$mainCash = (float) $mainQuery->sum('cash');
|
||||
|
||||
$productIds = $this->mainWalletProductIds();
|
||||
if ($productIds === []) {
|
||||
return $mainCash;
|
||||
}
|
||||
|
||||
$orphanedQuery = Wallet::query()
|
||||
->where('owner', $ownerId)
|
||||
->whereNull('fund_id')
|
||||
->whereIn('product_id', $productIds);
|
||||
if ($ownerType !== null) {
|
||||
$orphanedQuery->where('owner_type', $ownerType);
|
||||
}
|
||||
$orphanedCash = (float) $orphanedQuery->sum('cash');
|
||||
|
||||
return $mainCash + $orphanedCash;
|
||||
}
|
||||
|
||||
/**
|
||||
* انتقال موجودی کیف legacy یک محصول متصل به کیف اصلی — مثل goldali (idempotent).
|
||||
* خرید/فروش بعد از این فقط روی یک کیف (اصلی) کسر/واریز میشود.
|
||||
*/
|
||||
public function consolidateOrphanedForOwner(int $ownerId, int $ownerType, int $productId): bool
|
||||
{
|
||||
if (!$this->configService->isMainWalletProduct($productId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$productWallet = Wallet::query()
|
||||
->where('owner', $ownerId)
|
||||
->where('owner_type', $ownerType)
|
||||
->where('product_id', $productId)
|
||||
->whereNull('fund_id')
|
||||
->first();
|
||||
|
||||
if (!$productWallet) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$goldToMove = (float) $productWallet->gold;
|
||||
$cashToMove = (float) $productWallet->cash;
|
||||
|
||||
if (abs($goldToMove) < 1e-12 && abs($cashToMove) < 1e-12) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DB::transaction(function () use ($ownerId, $ownerType, $productWallet, $goldToMove, $cashToMove) {
|
||||
$mainWallet = Wallet::query()->firstOrCreate(
|
||||
[
|
||||
'owner' => $ownerId,
|
||||
'owner_type' => $ownerType,
|
||||
'fund_id' => null,
|
||||
'product_id' => null,
|
||||
],
|
||||
['gold' => 0, 'cash' => 0]
|
||||
);
|
||||
|
||||
$mainWallet->gold = (float) $mainWallet->gold + $goldToMove;
|
||||
$mainWallet->cash = (float) $mainWallet->cash + $cashToMove;
|
||||
$mainWallet->save();
|
||||
|
||||
$productWallet->gold = 0;
|
||||
$productWallet->cash = 0;
|
||||
$productWallet->save();
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** ادغام همهٔ کیفهای legacy محصولات main_wallet_products برای یک کاربر */
|
||||
public function consolidateAllMainWalletProductsForOwner(int $ownerId, int $ownerType): void
|
||||
{
|
||||
foreach ($this->mainWalletProductIds() as $productId) {
|
||||
$this->consolidateOrphanedForOwner($ownerId, $ownerType, (int) $productId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* طلای داخل قلکهای یک محصول (یا همهٔ محصولات main_wallet اگر $productId=null و فقط main).
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user