From c155d49070c0e6ae24f898f4dab4fb777643235a Mon Sep 17 00:00:00 2001 From: adonis Date: Mon, 6 Jul 2026 17:06:03 +0330 Subject: [PATCH] fix bug --- .../Customer/ProductController.php | 24 +++++++-- .../Controllers/Customer/WalletController.php | 20 +++---- app/Models/File.php | 31 ++++++++--- app/Services/AssetSummaryService.php | 52 +++++++++++++++++++ 4 files changed, 108 insertions(+), 19 deletions(-) diff --git a/app/Http/Controllers/Customer/ProductController.php b/app/Http/Controllers/Customer/ProductController.php index 42c695d..0540998 100644 --- a/app/Http/Controllers/Customer/ProductController.php +++ b/app/Http/Controllers/Customer/ProductController.php @@ -7,6 +7,7 @@ use App\Http\Controllers\Controller; use App\Http\Controllers\SuperController; use App\Models\Fund; use App\Models\Product; +use App\Services\AssetSummaryService; use Illuminate\Http\Request; use Rooyesh\Wallet\interfaces\TransactionInterface; use Rooyesh\Wallet\interfaces\WalletInterface; @@ -26,10 +27,13 @@ class ProductController extends SuperController $query = Product::with($this->with); parent::__construct($model, $this->with, $select, null,$query,$search); } - public function pTable(Request $request) + public function pTable(Request $request, AssetSummaryService $assetSummaryService) { $user = auth('customer')->user(); $mainWalletProductIds = app(\App\Services\ConfigService::class)->mainWalletProductIds(); + $inventoryByProduct = collect( + $assetSummaryService->buildForCustomer((int) $user->id, (int) $user->type)['inventory_cards'] ?? [] + )->keyBy('product_id'); $products = Product::where(function ($query) use ($user, $mainWalletProductIds) { $query->whereHas('wallet', function ($q) use ($user) { @@ -70,7 +74,7 @@ class ProductController extends SuperController } // Prepare the response - $user['rows'] = $products->map(function ($product) use ($user, $representativeId, $mainWalletGold) { + $user['rows'] = $products->map(function ($product) use ($user, $representativeId, $mainWalletGold, $inventoryByProduct) { $product->unit = self::productQuantityUnit([ 'unit' => $product->unit ?? null, 'direct_price' => $product->direct_price ?? null, @@ -81,12 +85,26 @@ class ProductController extends SuperController $product->file->setAttribute('full_src', $product->file->src); } + $card = $inventoryByProduct->get((int) $product->id); + $displayQty = $card !== null + ? (float) ($card['quantity'] ?? 0) + : null; + if ($representativeId !== null && (int) $product->id === $representativeId) { // کیف محصول فقط نقش هندل را دارد؛ موجودی واقعی از کیف اصلی است $walletInterface = new WalletInterface($user->id, $user->type, null, $product->id); $handleWallet = $walletInterface->wallet; - $handleWallet->gold = $mainWalletGold; + $handleWallet->gold = $displayQty ?? $mainWalletGold; $product->setRelation('wallet', $handleWallet); + } elseif ($displayQty !== null) { + if ($product->wallet) { + $product->wallet->gold = $displayQty; + } else { + $walletInterface = new WalletInterface($user->id, $user->type, null, $product->id); + $handleWallet = $walletInterface->wallet; + $handleWallet->gold = $displayQty; + $product->setRelation('wallet', $handleWallet); + } } return $product; diff --git a/app/Http/Controllers/Customer/WalletController.php b/app/Http/Controllers/Customer/WalletController.php index b949f36..9967e4a 100644 --- a/app/Http/Controllers/Customer/WalletController.php +++ b/app/Http/Controllers/Customer/WalletController.php @@ -319,6 +319,7 @@ class WalletController extends Controller if (!$data['adress'] || $data['adress']->customer_id != $data['customer']->id) { return response()->json(['message' => 'آدرس معتبر نیست یا متعلق به شما نمی‌باشد'], 403); } + $assetSummaryService = app(AssetSummaryService::class); foreach ($data['wallets'] as $key => $wallet) { $data['wallets'][$key]['wallet'] = Wallet::with(["product"])->find($wallet['wallet_id']); if (!$data['wallets'][$key]['wallet']) { @@ -332,16 +333,15 @@ class WalletController extends Controller return response()->json(['message' => 'محصولی در ولت مورد نظر یافت نشد.'], 422); } - // محصول متصل به کیف اصلی (main_wallet_products): موجودی و تراکنش روی کیف اصلی است - $effectiveProductId = self::effectiveProductWalletId((int) $data['wallets'][$key]['wallet']['product_id']); - $availableGold = $data['wallets'][$key]['wallet']['gold']; - if ($effectiveProductId === null) { - $mainWallet = Wallet::where('owner', auth('customer')->id()) - ->whereNull('fund_id') - ->whereNull('product_id') - ->first(); - $availableGold = (float) ($mainWallet->gold ?? 0); - } + $productId = (int) $data['wallets'][$key]['wallet']['product_id']; + $customerId = (int) $data['customer']['id']; + $ownerType = (int) auth('customer')->user()->type; + + // موجودی و کیف مؤثر — همسان با assets-summary و صفحهٔ اصلی + $effectiveProductId = $assetSummaryService + ->effectiveProductWalletIdForCustomer($customerId, $ownerType, $productId); + $availableGold = $assetSummaryService + ->productDisplayQuantity($customerId, $ownerType, $productId); if ($data['wallets'][$key]['value'] > $availableGold){ return response()->json([ diff --git a/app/Models/File.php b/app/Models/File.php index 6e0fa61..bb79204 100644 --- a/app/Models/File.php +++ b/app/Models/File.php @@ -111,22 +111,36 @@ class File extends Model { $fromSettings = self::baseUrlFromSettings(); if ($fromSettings !== '') { - return $fromSettings; + return self::ensureAbsoluteUrl($fromSettings); } $domain = config('app.domain'); if (is_string($domain) && $domain !== '' && ! str_contains($domain, 'localhost')) { - return self::ensureServerPublicBase(rtrim($domain, '/')); + return self::ensureAbsoluteUrl(self::ensureServerPublicBase(rtrim($domain, '/'))); } $appUrl = config('app.url'); if (is_string($appUrl) && $appUrl !== '' && ! str_contains($appUrl, 'localhost')) { - return self::ensureServerPublicBase(rtrim($appUrl, '/')); + return self::ensureAbsoluteUrl(self::ensureServerPublicBase(rtrim($appUrl, '/'))); } return ''; } + private static function ensureAbsoluteUrl(string $base): string + { + $base = rtrim(trim($base), '/'); + if ($base === '') { + return ''; + } + + if (! preg_match('/^https?:\/\//i', $base)) { + $base = 'https://'.ltrim($base, '/'); + } + + return $base; + } + private static function baseUrlFromSettings(): string { try { @@ -137,7 +151,7 @@ class File extends Model foreach (['server_url', 'bace_url'] as $key) { $value = trim((string) ($rows[$key] ?? '')); - if ($value !== '' && preg_match('/^https?:\/\//i', $value)) { + if ($value !== '') { return rtrim($value, '/'); } } @@ -148,8 +162,13 @@ class File extends Model } $siteUrl = trim((string) ($rows['app_url'] ?? '')); - if ($siteUrl !== '' && preg_match('/^https?:\/\//i', $siteUrl)) { - return rtrim($siteUrl, '/').'/server'; + if ($siteUrl !== '') { + $siteUrl = rtrim($siteUrl, '/'); + if (! preg_match('#/server$#i', $siteUrl)) { + $siteUrl .= '/server'; + } + + return $siteUrl; } } catch (\Throwable) { } diff --git a/app/Services/AssetSummaryService.php b/app/Services/AssetSummaryService.php index f44ae3e..e465b69 100644 --- a/app/Services/AssetSummaryService.php +++ b/app/Services/AssetSummaryService.php @@ -260,6 +260,7 @@ class AssetSummaryService 'unit_weight' => $this->productUnitWeightLabel($catalogProduct), 'show_in_assets' => $this->shouldShowInAssets($catalogProduct), 'is_melted' => true, + 'is_main_wallet' => true, 'file' => $this->filePayload($catalogProduct), ]; } @@ -267,6 +268,57 @@ class AssetSummaryService return $cards; } + /** + * کارت موجودی یک محصول از assets-summary — منبع واحد با صفحهٔ اصلی و کیف پول. + */ + public function productInventoryCard(int $customerId, int $ownerType, int $productId): ?array + { + $summary = $this->buildForCustomer($customerId, $ownerType); + + foreach ($summary['inventory_cards'] as $card) { + if ((int) ($card['product_id'] ?? 0) === $productId) { + return $card; + } + } + + return null; + } + + /** موجودی نمایشی محصول — همسان با inventory_cards */ + public function productDisplayQuantity(int $customerId, int $ownerType, int $productId): float + { + $card = $this->productInventoryCard($customerId, $ownerType, $productId); + if ($card !== null) { + return (float) ($card['quantity'] ?? 0); + } + + $wallet = Wallet::query() + ->where('owner', $customerId) + ->where('owner_type', $ownerType) + ->where('product_id', $productId) + ->whereNull('fund_id') + ->first(); + + return (float) ($wallet->gold ?? 0); + } + + /** + * کیف مؤثر برای برداشت/تحویل فیزیکی — null یعنی کیف اصلی. + */ + public function effectiveProductWalletIdForCustomer(int $customerId, int $ownerType, int $productId): ?int + { + if ($this->configService->isMainWalletProduct($productId)) { + return null; + } + + $card = $this->productInventoryCard($customerId, $ownerType, $productId); + if ($card !== null && !empty($card['is_main_wallet'])) { + return null; + } + + return $productId; + } + private function resolveMainWallet(Collection $userWallets): ?Wallet { return $userWallets->first(