firstOrFail(); $zone = match (true) { $type === ShipmentType::Parcel && $direction === 'export' => $country->export_zone_parcel, $type === ShipmentType::Parcel && $direction === 'import' => $country->import_zone_parcel, $type !== ShipmentType::Parcel && $direction === 'export' => $country->export_zone_doc, $type !== ShipmentType::Parcel && $direction === 'import' => $country->import_zone_doc, }; $rate = $this->lookupRate($direction, $type, $chargeableWeight, $zone); $profitMargin = (float) SystemSetting::get('profit_margin', 1.25); $aedToIrr = (float) SystemSetting::get('aed_to_irr', 455000); $vatRate = (float) SystemSetting::get('vat_rate', 0.09); $packingCostDefault = (float) SystemSetting::get('packing_cost_default', 100000); $netDirham = $rate * $profitMargin; $netRial = $netDirham * $aedToIrr; $extraService = (float) ($data['extra_service'] ?? 0); $packingCost = (float) ($data['packing_cost'] ?? $packingCostDefault); $domesticPickup = (float) ($data['domestic_pickup'] ?? 0); $domesticDelivery = (float) ($data['domestic_delivery'] ?? 0); $warehousingCost = (float) ($data['warehousing_cost'] ?? 0); // متغیر $discount را از آرایه داده‌ها دریافت می‌کنیم (اگر وجود داشته باشد) // اما در اینجا ما از کد تخفیف استفاده می‌کنیم، پس این خط را حذف یا اصلاح می‌کنیم // $discount = (float) ($data['discount'] ?? 0); // محاسبه قیمت اولیه قبل از تخفیف کد $subtotal = $netRial + $extraService + $packingCost + $domesticPickup + $domesticDelivery + $warehousingCost; // اعمال کد تخفیف (در صورت وجود) $discountCode = $data['discount_code'] ?? null; $discountResult = $this->applyDiscount($subtotal, $discountCode); if ($discountResult['success']) { $finalPrice = $discountResult['final_price']; // افزایش شمارنده استفاده از کد تخفیف $discount = DiscountCode::where('code', $discountResult['discount_code'])->first(); if ($discount) { $discount->increment('used_count'); } } else { $finalPrice = $subtotal; } $totalFee = $finalPrice * (1 + $vatRate); $vatAmount = $totalFee - $finalPrice; return [ 'base_price' => $rate, 'net_dirham' => $netDirham, 'net_rial' => $netRial, 'extra_service' => $extraService, 'packing_cost' => $packingCost, 'domestic_pickup' => $domesticPickup, 'domestic_delivery' => $domesticDelivery, 'warehousing_cost' => $warehousingCost, 'discount_applied' => $discountResult['success'], 'discount_amount' => $discountResult['discount_amount'], 'discount_message' => $discountResult['message'], 'vat_amount' => $vatAmount, 'total_fee' => $totalFee, 'zone' => $zone, 'chargeable_weight' => $chargeableWeight, ]; } /** * اعمال کد تخفیف روی قیمت نهایی * * @param float $totalPrice قیمت کل قبل از تخفیف * @param string|null $code کد تخفیف وارد شده توسط کاربر * @return array ['success' => bool, 'message' => string, 'discount_amount' => float, 'final_price' => float] */ public function applyDiscount(float $totalPrice, ?string $code): array { if (empty($code)) { return [ 'success' => false, 'message' => 'کد تخفیف وارد نشده است.', 'discount_amount' => 0, 'final_price' => $totalPrice, ]; } $discount = DiscountCode::where('code', $code)->first(); // 1. بررسی وجود کد if (!$discount) { return [ 'success' => false, 'message' => 'کد تخفیف نامعتبر است.', 'discount_amount' => 0, 'final_price' => $totalPrice, ]; } // 2. بررسی فعال بودن کد if (!$discount->is_active) { return [ 'success' => false, 'message' => 'این کد تخفیف غیرفعال شده است.', 'discount_amount' => 0, 'final_price' => $totalPrice, ]; } // 3. بررسی تاریخ انقضا if ($discount->expires_at && $discount->expires_at->isPast()) { return [ 'success' => false, 'message' => 'این کد تخفیف منقضی شده است.', 'discount_amount' => 0, 'final_price' => $totalPrice, ]; } // 4. بررسی حداقل مبلغ سفارش if ($discount->min_order_amount > 0 && $totalPrice < $discount->min_order_amount) { return [ 'success' => false, 'message' => "حداقل مبلغ سفارش برای استفاده از این کد " . number_format($discount->min_order_amount) . " ریال است.", 'discount_amount' => 0, 'final_price' => $totalPrice, ]; } // 5. بررسی محدودیت استفاده if ($discount->usage_limit && $discount->used_count >= $discount->usage_limit) { return [ 'success' => false, 'message' => 'ظرفیت استفاده از این کد تخفیف به پایان رسیده است.', 'discount_amount' => 0, 'final_price' => $totalPrice, ]; } // محاسبه مبلغ تخفیف $discountAmount = 0; if ($discount->type === 'percentage') { $discountAmount = ($totalPrice * $discount->value) / 100; } elseif ($discount->type === 'fixed') { $discountAmount = $discount->value; } // اطمینان از اینکه تخفیف بیشتر از مبلغ کل نشود $discountAmount = min($discountAmount, $totalPrice); $finalPrice = $totalPrice - $discountAmount; return [ 'success' => true, 'message' => 'کد تخفیف با موفقیت اعمال شد.', 'discount_amount' => $discountAmount, 'final_price' => $finalPrice, 'discount_code' => $discount->code, // برای ذخیره در سفارش ]; } private function lookupRate(string $direction, ShipmentType $type, float $weight, int $zone): float { $zoneColumn = 'zone_' . $zone; $rate = \App\Models\ShippingRate::query() ->where('direction', $direction) ->where('type', $type->value) ->where('weight', '<=', $weight) ->where($zoneColumn, '>', 0) ->orderByDesc('weight') ->value($zoneColumn); if ($rate === null) { throw new InvalidArgumentException('No rate found for the given parameters.'); } return (float) $rate; } }