155 lines
4.8 KiB
PHP
155 lines
4.8 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Product;
|
|
use Rooyesh\Wallet\models\Wallet;
|
|
|
|
class TransactionMetalService
|
|
{
|
|
private const METAL_LABELS = [
|
|
1 => 'طلا',
|
|
2 => 'نقره',
|
|
3 => 'مس',
|
|
];
|
|
|
|
public function __construct(
|
|
private readonly ConfigService $configService
|
|
) {
|
|
}
|
|
|
|
public function metalLabel(int $metalId): string
|
|
{
|
|
return self::METAL_LABELS[$metalId] ?? Controller::metalTypeLabel();
|
|
}
|
|
|
|
/** @return array<int, array{metal_id: int, label: string, display_unit: string}> */
|
|
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<int, array<string, mixed>|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;
|
|
}
|
|
}
|