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);
+1
View File
@@ -25,6 +25,7 @@ class Order extends Model
'service_charge_percentage',//درصد کارمزد
'service_charge',//میزان کارمزد
'service_charge_price',//مبلغ کارمزد به ریال
'fee_asset',//سمت کسر کارمزد: gold یا rial
'payment_sts',
'payment_amount',//میزان پرداخت شده
'payment_remind',//میزان مبلغ باقی مانده
+27
View File
@@ -0,0 +1,27 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class ProfitConversion extends Model
{
use HasFactory;
protected $fillable = [
'user_id',
'rial_amount',
'gram_amount',
'unit_price',
'converted_at',
'description',
];
protected $casts = [
'rial_amount' => 'float',
'gram_amount' => 'float',
'unit_price' => 'float',
'converted_at' => 'datetime',
];
}
@@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
if (!Schema::hasTable('orders')) {
return;
}
Schema::table('orders', function (Blueprint $table) {
if (!Schema::hasColumn('orders', 'fee_asset')) {
// سمت کسر کارمزد: 'gold' یعنی از طلا کسر شده، 'rial' یعنی از ریال.
$table->string('fee_asset', 8)->nullable()->after('service_charge_price');
}
});
}
public function down(): void
{
if (!Schema::hasTable('orders')) {
return;
}
Schema::table('orders', function (Blueprint $table) {
if (Schema::hasColumn('orders', 'fee_asset')) {
$table->dropColumn('fee_asset');
}
});
}
};
@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
if (Schema::hasTable('profit_conversions')) {
return;
}
Schema::create('profit_conversions', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id')->nullable();
$table->decimal('rial_amount', 20, 0)->default(0); // مبلغ ریالی سود که تبدیل شد
$table->decimal('gram_amount', 16, 4)->default(0); // معادل طلا (گرم)
$table->decimal('unit_price', 20, 0)->default(0); // مظنه/قیمت هر گرم هنگام تبدیل
$table->dateTime('converted_at')->nullable(); // تاریخ سند
$table->string('description', 500)->nullable();
$table->timestamps();
$table->index('converted_at');
});
}
public function down(): void
{
Schema::dropIfExists('profit_conversions');
}
};
+4
View File
@@ -157,6 +157,10 @@ Route::middleware('auth:user')->group(function (){
Route::post('dashboard/customer/single/all_sell', [DashboardController::class, 'sumSellToCustomerSingle']);
Route::post('dashboard/customer/flow', [DashboardController::class, 'flow']);
Route::post('dashboard/customer/order-peak-hours', [DashboardController::class, 'orderPeakHours']);
// سند تبدیل سود ریالی به طلا
Route::post('dashboard/profit-conversions', [DashboardController::class, 'profitConversions']);
Route::post('dashboard/profit-conversions/store', [DashboardController::class, 'storeProfitConversion']);
Route::delete('dashboard/profit-conversions/{id}', [DashboardController::class, 'deleteProfitConversion']);
//bank account
Route::post('account/table', [BankAccountController::class, 'table']);