change transition structure 2

This commit is contained in:
2026-07-10 23:29:36 +03:30
parent 028c5d5938
commit 47a2f8e6bf
7 changed files with 226 additions and 1 deletions
@@ -8,6 +8,7 @@ use App\Models\Customer;
use App\Models\Order;
use App\Models\Price;
use App\Models\Product;
use App\Models\ProfitConversion;
use App\Models\TransactionsAdmin;
use App\Models\Withdraw;
use App\Services\BalanceReportService;
@@ -320,7 +321,12 @@ class DashboardController extends Controller
"orderCount" => $ords->count(),
"Gifts" => 0,
"GiftsPrise" => 0,
"sumAll" => 0
"sumAll" => 0,
// تفکیک سود بر اساس سمت کسر کارمزد
"profitGoldGrams" => 0, // سود طلایی: مجموع کارمزدهای کسرشده از طلا (گرم)
"profitRial" => 0, // سود ریالی: مجموع کارمزدهای کسرشده از ریال (ریال)
"profitGoldValueRial" => 0,
"daily" => [],
];
// Calculate total gold gifts from transactions
@@ -333,12 +339,50 @@ class DashboardController extends Controller
$lastGoldPrice = (float) (Price::latest()->first()?->price ?? 0);
$response['GiftsPrise'] = $lastGoldPrice > 0 ? (int) floor($giftsGold * $lastGoldPrice) : 0;
// Calculate order-related sums
$daily = [];
foreach ($ords as $ord) {
$response['fullPriceM1'] += abs($ord->total_price_original - $ord->payment_amount);
$response['fullPriceM2'] += $ord->service_charge_price + $ord->total_fee;
$response['fullPriceSood'] += $ord->total_fee;
$response['fullPriceKarmozd'] += $ord->service_charge_price;
// تفکیک کارمزد به طلا/ریال بر اساس سمت کسر
// fee_asset === 'gold' → کارمزد از طلا گرفته شده (گرم)؛ در غیر این صورت ریالی محسوب می‌شود.
$feeFromGold = $ord->fee_asset === 'gold';
$goldFeeGrams = $feeFromGold ? (float) $ord->service_charge : 0.0;
$rialFee = $feeFromGold ? 0.0 : (float) $ord->service_charge_price;
$response['profitGoldGrams'] += $goldFeeGrams;
$response['profitRial'] += $rialFee;
$dateKey = $ord->created_at ? Carbon::parse($ord->created_at)->toDateString() : 'نامشخص';
if (!isset($daily[$dateKey])) {
$daily[$dateKey] = [
'date' => $dateKey,
'profit_gold' => 0.0, // گرم
'profit_rial' => 0.0, // ریال (کارمزد ریالی)
'spread_rial' => 0.0, // سود اختلاف قیمت (ریال)
'order_count' => 0,
];
}
$daily[$dateKey]['profit_gold'] += $goldFeeGrams;
$daily[$dateKey]['profit_rial'] += $rialFee;
$daily[$dateKey]['spread_rial'] += (float) $ord->total_fee;
$daily[$dateKey]['order_count']++;
}
// مرتب‌سازی نزولی بر اساس تاریخ و گرد کردن گرم‌ها
krsort($daily);
$response['daily'] = array_map(function ($row) {
$row['profit_gold'] = round($row['profit_gold'], 4);
return $row;
}, array_values($daily));
$response['profitGoldGrams'] = round($response['profitGoldGrams'], 4);
$response['profitGoldValueRial'] = $lastGoldPrice > 0
? (int) floor($response['profitGoldGrams'] * $lastGoldPrice)
: 0;
$response['totalTradingProfit'] = $response['fullPriceSood'] + $response['fullPriceKarmozd'];
$response['sumAll'] = $response['fullPriceM1'] - $response['GiftsPrise'];
return $response;
@@ -462,4 +506,79 @@ class DashboardController extends Controller
'total_orders' => array_sum(array_column($hours, 'total')),
]);
}
/**
* لیست سندهای تبدیل سود ریالی به طلا در یک بازه + جمع کل.
*/
public function profitConversions(Request $request)
{
$query = ProfitConversion::query();
if ($request->filled('startDate')) {
$query->where('converted_at', '>=', Carbon::parse($request->startDate)->startOfDay());
}
if ($request->filled('endDate')) {
$query->where('converted_at', '<=', Carbon::parse($request->endDate)->endOfDay());
}
$items = $query->orderByDesc('converted_at')->orderByDesc('id')->get();
return response()->json([
'items' => $items,
'totalRial' => (float) $items->sum('rial_amount'),
'totalGram' => round((float) $items->sum('gram_amount'), 4),
]);
}
/**
* ثبت سند تبدیل سود ریالی به طلا.
* اگر گرم ارسال نشود از روی مبلغ و قیمت واحد محاسبه می‌شود و بالعکس.
*/
public function storeProfitConversion(Request $request)
{
$data = $request->validate([
'rial_amount' => 'nullable|numeric|min:0',
'gram_amount' => 'nullable|numeric|min:0',
'unit_price' => 'nullable|numeric|min:0',
'converted_at' => 'nullable|date',
'description' => 'nullable|string|max:500',
]);
$unitPrice = (float) ($data['unit_price'] ?? 0);
if ($unitPrice <= 0) {
$unitPrice = (float) (Price::latest()->first()?->price ?? 0);
}
$rial = (float) ($data['rial_amount'] ?? 0);
$gram = (float) ($data['gram_amount'] ?? 0);
if ($gram <= 0 && $rial > 0 && $unitPrice > 0) {
$gram = round($rial / $unitPrice, 4);
} elseif ($rial <= 0 && $gram > 0 && $unitPrice > 0) {
$rial = round($gram * $unitPrice);
}
if ($rial <= 0 && $gram <= 0) {
throw new \Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException('مبلغ ریالی یا وزن طلا را وارد کنید.');
}
$conversion = ProfitConversion::create([
'user_id' => optional($request->user())->id,
'rial_amount' => $rial,
'gram_amount' => $gram,
'unit_price' => $unitPrice,
'converted_at' => !empty($data['converted_at']) ? Carbon::parse($data['converted_at']) : now(),
'description' => $data['description'] ?? null,
]);
return response()->json($conversion, 201);
}
public function deleteProfitConversion($id)
{
$conversion = ProfitConversion::findOrFail($id);
$conversion->delete();
return response()->json(['deleted' => true]);
}
}
@@ -275,6 +275,9 @@ class SingleOrderController extends Controller
$data['payment_amount'] = $data['total_price'] + $data['service_charge_price'];
}
// سمت کسر کارمزد برای گزارش تفکیک‌شده در داشبورد
$data['fee_asset'] = $rialLocked ? 'gold' : 'rial';
$this->enforceProductOrderLimits($data);
if (!empty($data['first_buy']) && ($minFirstBuy = Setting::where('is_active', 1)->where('key', 'min_first_buy')->value('value'))) {
@@ -514,6 +517,9 @@ class SingleOrderController extends Controller
$goldDebit = $data['amount'];
}
// سمت کسر کارمزد برای گزارش تفکیک‌شده در داشبورد
$data['fee_asset'] = $rialLocked ? 'gold' : 'rial';
$grossTotal = $data['amount'] * $data['price'];
$this->enforceProductOrderLimits($data, (float) $grossTotal);