fix: resolve copper unit kilogram display and asset valuation calculations

This commit is contained in:
2026-11-07 12:24:19 +03:30
parent 7dd5304638
commit 808c272e0c
3 changed files with 83 additions and 25 deletions
+12 -5
View File
@@ -503,19 +503,26 @@ class Controller extends BaseController
/** واحد وزن معاملات فلز — در بورس مس پیش‌فرض کیلوگرم است */
public static function tradeWeightUnit(): string
{
return self::resolveTradeWeightUnit(
app(ConfigService::class)->getString('unit')
);
$value = app(ConfigService::class)->getString('unit');
$resolved = self::resolveTradeWeightUnit($value);
// در بورس مس واحد پایه همیشه کیلوگرم است
if ($resolved === 'گرم' || empty($value)) {
return 'کیلوگرم';
}
return $resolved;
}
public static function resolveTradeWeightUnit(?string $value): string
{
$unit = trim((string) $value);
if ($unit === 'گرم' || $unit === 'gram' || $unit === 'g') {
return 'گرم';
if ($unit === 'کیلوگرم' || $unit === 'kg' || $unit === 'kilogram') {
return 'کیلوگرم';
}
// در بورس مس واحد مبنا کیلوگرم است
return 'کیلوگرم';
}
+56 -19
View File
@@ -148,11 +148,17 @@ class AssetSummaryService
float $assetsRialValue,
float $totalRialValue
): array {
$goldMetal = collect($metalTotals)->first(fn (array $row) => (int) ($row['metal_id'] ?? 0) === 1);
$goldWeight = (float) ($goldMetal['total_weight'] ?? 0);
$liveGoldPrice = $this->resolveLivePricePerUnit(1);
$goldRialValue = $goldWeight > 0 && $liveGoldPrice > 0
? round($goldWeight * $liveGoldPrice, 0)
$mainMetalId = $this->walletBalanceService->resolveMainWalletMetalId();
$primaryMetal = collect($metalTotals)->first(fn (array $row) => (int) ($row['metal_id'] ?? 0) === (int) $mainMetalId)
?? collect($metalTotals)->first(fn (array $row) => (int) ($row['metal_id'] ?? 0) === 3)
?? collect($metalTotals)->first(fn (array $row) => (int) ($row['metal_id'] ?? 0) === 1)
?? collect($metalTotals)->first();
$activeMetalId = (int) ($primaryMetal['metal_id'] ?? $mainMetalId);
$metalWeight = (float) ($primaryMetal['total_weight'] ?? 0);
$livePrice = $this->resolveLivePricePerUnit($activeMetalId);
$metalRialValue = $metalWeight > 0 && $livePrice > 0
? round($metalWeight * $livePrice, 0)
: 0.0;
$averageBuyPrice = null;
@@ -161,7 +167,7 @@ class AssetSummaryService
$unrealizedProfitPercent = null;
$unrealizedProfitGold = null;
if ($goldWeight > 0) {
if ($metalWeight > 0) {
$buyOrders = Order::query()
->where('customer_id', $customerId)
->where('direction', 1)
@@ -174,14 +180,14 @@ class AssetSummaryService
if ($totalBought > 0 && $weightedSum > 0) {
$averageBuyPrice = round($weightedSum / $totalBought, 0);
$costBasisRial = round($averageBuyPrice * $goldWeight, 0);
$unrealizedProfitRial = round($goldRialValue - $costBasisRial, 0);
$costBasisRial = round($averageBuyPrice * $metalWeight, 0);
$unrealizedProfitRial = round($metalRialValue - $costBasisRial, 0);
if ($costBasisRial > 0) {
$unrealizedProfitPercent = round(($unrealizedProfitRial / $costBasisRial) * 100, 2);
}
// سود طلایی: همان سود ریالی تبدیل‌شده به وزن طلا با قیمت زندهٔ امروز
if ($liveGoldPrice > 0) {
$unrealizedProfitGold = round($unrealizedProfitRial / $liveGoldPrice, 4);
// سود وزنی: همان سود ریالی تبدیل‌شده به وزن فلز با قیمت زندهٔ امروز
if ($livePrice > 0) {
$unrealizedProfitGold = round($unrealizedProfitRial / $livePrice, 4);
}
}
}
@@ -190,14 +196,17 @@ class AssetSummaryService
'total_rial_value' => round($totalRialValue, 0),
'cash_rial' => round($cashWallet, 0),
'metal_rial_value' => round($assetsRialValue, 0),
'gold_weight' => round($goldWeight, 3),
'gold_rial_value' => $goldRialValue,
'gold_weight' => round($metalWeight, 3),
'gold_rial_value' => $metalRialValue,
'copper_weight' => round($metalWeight, 3),
'copper_rial_value' => $metalRialValue,
'average_buy_price' => $averageBuyPrice,
'cost_basis_rial' => $costBasisRial,
'unrealized_profit_rial' => $unrealizedProfitRial,
'unrealized_profit_percent' => $unrealizedProfitPercent,
'unrealized_profit_gold' => $unrealizedProfitGold,
'live_gold_price' => round($liveGoldPrice, 0),
'live_gold_price' => round($livePrice, 0),
'live_copper_price' => round($livePrice, 0),
];
}
@@ -743,11 +752,9 @@ class AssetSummaryService
return 0.0;
}
if (count($catalogMetalIds) === 1) {
return (int) $catalogMetalIds[0] === (int) $metalId ? $mainWalletGrams : 0.0;
}
$mainMetalId = $this->walletBalanceService->resolveMainWalletMetalId();
return (int) $metalId === 1 ? $mainWalletGrams : 0.0;
return (int) $metalId === (int) $mainMetalId ? $mainWalletGrams : 0.0;
}
/**
@@ -797,8 +804,33 @@ class AssetSummaryService
private function resolveLivePricePerUnit(int $metalId): float
{
$prices = app(ProductDisplayPriceService::class);
$mainMetalId = $this->walletBalanceService->resolveMainWalletMetalId();
if ($metalId === 3 || $metalId === $mainMetalId) {
$copperProduct = Product::query()
->where('active', 1)
->where('metal_id', $metalId)
->orderBy('id')
->first();
if ($copperProduct) {
$base = (float) $prices->resolveOrderBasePrice($copperProduct);
if ($base > 0) {
return $base;
}
}
$live = (float) $prices->resolveAppBasePrice();
if ($live > 0) {
return $live;
}
return (float) (Price::latest('id')->value('price') ?? 0);
}
if ($metalId === 1) {
$live = (int) app(ProductDisplayPriceService::class)->resolveAppBasePrice();
$live = (int) $prices->resolveAppBasePrice();
if ($live > 0) {
return (float) $live;
}
@@ -817,6 +849,11 @@ class AssetSummaryService
return 0.0;
}
$base = (float) $prices->resolveOrderBasePrice($product);
if ($base > 0) {
return $base;
}
$unitPrice = $this->productDisplayUnitPrice($product);
$amount = (float) ($product->amount ?? 1);
+15 -1
View File
@@ -317,10 +317,24 @@ class WalletBalanceService
->orderBy('id')
->first();
return max(1, (int) ($product?->metal_id ?? 1));
if ($product && (int) ($product->metal_id ?? 0) > 0) {
return (int) $product->metal_id;
}
}
// در بورس مس، مس فلز اصلی پلتفرم است
$hasCopperProduct = Product::query()
->where('active', 1)
->where('metal_id', 3)
->exists();
if ($hasCopperProduct) {
return 3;
}
$metalIds = $this->catalogMetalIds();
if (in_array(3, $metalIds, true)) {
return 3;
}
return count($metalIds) === 1 ? (int) $metalIds[0] : 1;
}