'طلا', 2 => 'نقره', 3 => 'مس', ]; public function __construct( private readonly ConfigService $configService ) { } public function metalLabel(int $metalId): string { return self::METAL_LABELS[$metalId] ?? Controller::metalTypeLabel(); } /** @return array */ public function catalogMetals(): array { return Product::query() ->where('active', 1) ->pluck('metal_id') ->filter(fn ($id) => (int) $id > 0) ->map(fn ($id) => (int) $id) ->unique() ->sort() ->values() ->map(fn (int $metalId) => [ 'metal_id' => $metalId, 'label' => $this->metalLabel($metalId), 'display_unit' => Controller::tradeWeightUnit(), ]) ->all(); } public function resolveMetalIdForTransaction(object $transaction): int { $productId = (int) ($transaction->product_id ?? 0); if ($productId > 0) { $metalId = (int) (Product::query()->whereKey($productId)->value('metal_id') ?? 0); if ($metalId > 0) { return $metalId; } } $wallet = $transaction->wallet ?? null; if (is_numeric($wallet)) { $wallet = Wallet::with('product:id,metal_id')->find($wallet); } elseif (is_object($wallet) && !$wallet->relationLoaded('product')) { $wallet->load('product:id,metal_id'); } if (is_object($wallet) && $wallet->product_id && $wallet->product) { $metalId = (int) ($wallet->product->metal_id ?? 0); if ($metalId > 0) { return $metalId; } } if ($this->isMainWalletMetalTransaction($transaction, $wallet)) { return $this->configService->mainWalletMetalId(); } return 1; } private function isMainWalletMetalTransaction(object $transaction, mixed $wallet): bool { $type = (int) ($transaction->type ?? 0); if (!in_array($type, [1, 2, 7, 10], true)) { return false; } if (!$wallet || !is_object($wallet)) { return true; } return $wallet->product_id === null && $wallet->fund_id === null; } public function resolveDisplayTypeStr(object $transaction): ?string { $type = (int) ($transaction->type ?? 0); if (!in_array($type, [1, 2, 7, 10], true)) { return null; } $metalLabel = $this->metalLabel($this->resolveMetalIdForTransaction($transaction)); return match ($type) { 1 => Controller::productBuyTitle($metalLabel), 2 => Controller::productSellTitle($metalLabel), 7 => 'واریز ' . $metalLabel, 10 => 'برداشت ' . $metalLabel, default => null, }; } /** @param iterable|object> $rows */ public function enrichTransactionRows(iterable $rows): array { $metalIds = array_column($this->catalogMetals(), 'metal_id'); $enriched = []; foreach ($rows as $row) { $record = is_array($row) ? (object) $row : $row; $metalId = $this->resolveMetalIdForTransaction($record); $displayType = $this->resolveDisplayTypeStr($record); $type = (int) (is_array($row) ? ($row['type'] ?? 0) : ($row->type ?? 0)); $gold = (float) (is_array($row) ? ($row['gold'] ?? 0) : ($row->gold ?? 0)); $isMoney = in_array($type, [3, 4], true); if ($displayType !== null) { if (is_array($row)) { $row['type_str'] = $displayType; } else { $row->type_str = $displayType; } } foreach ($metalIds as $mid) { $key = "metal_gold_{$mid}"; $value = (!$isMoney && $metalId === $mid) ? $gold : 0; if (is_array($row)) { $row[$key] = $value; } else { $row->{$key} = $value; } } if (is_array($row)) { $row['transaction_metal_id'] = $metalId; $row['transaction_metal_label'] = $this->metalLabel($metalId); } else { $row->transaction_metal_id = $metalId; $row->transaction_metal_label = $this->metalLabel($metalId); } $enriched[] = $row; } return $enriched; } }