77 lines
3.2 KiB
PHP
77 lines
3.2 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Country;
|
|
use App\Models\ShippingRate;
|
|
use App\Models\SystemSetting;
|
|
|
|
class PriceCalculatorService
|
|
{
|
|
/**
|
|
* محاسبه قیمت ارسال
|
|
*
|
|
* @param array $data (شامل: direction, type, origin_country_id, destination_country_id, weight, length, width, height)
|
|
* @return array
|
|
*/
|
|
public function calculate(array $data): array
|
|
{
|
|
// 1. محاسبه وزن حجمی (طبق استاندارد جهانی تقسیم بر 5000)
|
|
$dimensions = ($data['length'] * $data['width'] * $data['height']) / 5000;
|
|
|
|
// 2. تعیین وزن قابل پرداخت (ماکزیموم وزن واقعی و حجمی)
|
|
$chargeableWeight = max($data['weight'], $dimensions);
|
|
|
|
// 3. استخراج زون مقصد/مبدأ بر اساس جهت ارسال
|
|
if ($data['direction'] === 'export') {
|
|
// صادرات: زون صادرات کشور مقصد مد نظر است
|
|
$country = Country::find($data['destination_country_id']);
|
|
$zone = $country->export_zone;
|
|
} else {
|
|
// واردات: زون واردات کشور مبدأ مد نظر است
|
|
$country = Country::find($data['origin_country_id']);
|
|
$zone = $country->import_zone;
|
|
}
|
|
|
|
// 4. پیدا کردن ردیف تعرفه مناسب
|
|
// منطق: باید نزدیکترین وزنی که بزرگتر مساوی وزن ماست رو پیدا کنیم (مثلاً اگر 1.2 کیلو است، ردیف 1.5 را میگیرد)
|
|
$rateRecord = ShippingRate::where('direction', $data['direction'])
|
|
->where('type', $data['type'])
|
|
->where('weight', '>=', $chargeableWeight)
|
|
->orderBy('weight', 'asc')
|
|
->first();
|
|
|
|
// اگر وزن بالای 30 کیلو باشد یا رکوردی پیدا نشود (Spot Rate)
|
|
if (!$rateRecord) {
|
|
return [
|
|
'status' => 'error',
|
|
'message' => 'برای این وزن نرخ ثبت نشده است (نیاز به استعلام نرخ ویژه / Spot Rate).',
|
|
'chargeable_weight' => $chargeableWeight,
|
|
'volumetric_weight' => $dimensions,
|
|
];
|
|
}
|
|
|
|
// 5. استخراج قیمت پایه بر اساس زون (مثلاً ستون zone_3)
|
|
$zoneColumn = "zone_{$zone}";
|
|
$basePriceDirham = $rateRecord->$zoneColumn;
|
|
|
|
// 6. دریافت نرخ ارز و ضریب سود از تنظیمات
|
|
$settings = SystemSetting::first();
|
|
$dirhamRate = $settings->dirham_rate; // نرخ درهم به ریال
|
|
$profitPercent = $settings->profit_percent; // مثلاً 1.25
|
|
|
|
// 7. اجرای فرمول نهایی (دقیقاً مطابق اکسل)
|
|
$netDirham = $basePriceDirham * $profitPercent;
|
|
$netRial = $netDirham * $dirhamRate;
|
|
|
|
return [
|
|
'status' => 'success',
|
|
'volumetric_weight' => round($dimensions, 3),
|
|
'chargeable_weight' => round($chargeableWeight, 2),
|
|
'zone' => $zone,
|
|
'base_price_dirham' => $basePriceDirham,
|
|
'net_dirham' => round($netDirham, 2),
|
|
'net_rial' => round($netRial),
|
|
];
|
|
}
|
|
} |