'profit_margin', 'value' => 1.0]); // بدون سود SystemSetting::create(['key' => 'vat_rate', 'value' => 0.0]); // بدون مالیات // ۲. ایجاد کشور Country::factory()->create([ 'iso_code' => 'US', 'name' => 'United States', 'is_active' => true, ]); // ۳. نگاشت زون — جدول country_zones (سیستم ۴-رُبعی) CountryZone::create([ 'country_name' => 'United States', 'country_iso2' => 'US', 'document_zone' => 1, 'parcel_zone' => 1, ]); // ۴. نرخ حمل — جدول rate_entries، مستقیماً به ریال (IRR) RateEntry::create([ 'direction' => 'export', 'service_type' => 'document', 'weight' => 3.0, 'zone' => 1, 'rate' => 40000.0, // ۴۰,۰۰۰ ریال 'currency' => 'IRR', 'effective_at' => now()->subDay(), ]); // ۵. اجرای سرویس $service = app(PriceCalculatorService::class); $data = [ 'direction' => 'Outbound', // ← در سرویس به 'export' تبدیل می‌شود 'type' => 'DOC_NORMAL', 'country_iso' => 'US', 'weight' => 2.5, 'volumetric_weight' => 3.0, 'extra_service' => 10000, // ۱۰,۰۰۰ ریال 'packing_cost' => 0, 'domestic_pickup' => 0, 'domestic_delivery' => 0, 'warehousing_cost' => 0, ]; $result = $service->calculate($data); // ۶. بررسی ساختار خروجی $this->assertIsArray($result); $this->assertArrayHasKey('total_fee', $result); $this->assertArrayHasKey('base_price', $result); // ۷. بررسی مقادیر $this->assertEquals(1, $result['zone']); $this->assertEquals(3.0, $result['chargeable_weight']); $this->assertEquals(40000.0, $result['base_price']); $this->assertFalse($result['discount_applied']); // محاسبهٔ دستی (همه به ریال): // base_price = 40000 // net_rial = 40000 × 1.0 (سود) + 10000 (خدمات) = 50000 // vat = 0 // تخفیف = 0 // total_fee = گردش به نزدیک‌ترین ۱۰۰۰ = 50000 $this->assertEquals(50000, $result['total_fee']); $this->assertEquals(50000, $result['net_rial']); } #[Test] public function it_applies_discount_from_code_in_pricing() { SystemSetting::create(['key' => 'profit_margin', 'value' => 1.0]); SystemSetting::create(['key' => 'vat_rate', 'value' => 0.0]); Country::factory()->create([ 'iso_code' => 'DE', 'name' => 'Germany', 'is_active' => true, ]); CountryZone::create([ 'country_name' => 'Germany', 'country_iso2' => 'DE', 'document_zone' => 2, 'parcel_zone' => 2, ]); RateEntry::create([ 'direction' => 'export', 'service_type' => 'document', 'weight' => 1.0, 'zone' => 2, 'rate' => 100000.0, // ۱۰۰,۰۰۰ ریال 'currency' => 'IRR', 'effective_at' => now()->subDay(), ]); // کد تخفیف ۱۰٪ فعال با ظرفیت \App\Models\DiscountCode::create([ 'code' => 'PCT10', 'type' => 'percentage', 'value' => 10, 'usage_limit' => 10, 'used_count' => 0, 'is_active' => true, ]); $service = app(PriceCalculatorService::class); $result = $service->calculate([ 'direction' => 'export', 'type' => 'DOC_NORMAL', 'country_iso' => 'DE', 'weight' => 1.0, 'volumetric_weight' => 0, 'extra_service' => 0, 'packing_cost' => 0, 'domestic_pickup' => 0, 'domestic_delivery' => 0, 'warehousing_cost' => 0, 'discount_code' => 'PCT10', ]); // base = 100000، سود = 1.0، vat = 0 → subtotal = 100000 // تخفیف = ۱۰٪ = 10000 → total = 90000 (گردش به ۱۰۰۰) $this->assertTrue($result['discount_applied']); $this->assertEquals(10000, $result['discount_amount']); $this->assertEquals(90000, $result['total_fee']); } #[Test] public function it_ignores_discount_code_whose_usage_limit_is_reached() { SystemSetting::create(['key' => 'profit_margin', 'value' => 1.0]); SystemSetting::create(['key' => 'vat_rate', 'value' => 0.0]); Country::factory()->create([ 'iso_code' => 'AE', 'name' => 'United Arab Emirates', 'is_active' => true, ]); CountryZone::create([ 'country_name' => 'United Arab Emirates', 'country_iso2' => 'AE', 'document_zone' => 1, 'parcel_zone' => 1, ]); RateEntry::create([ 'direction' => 'export', 'service_type' => 'document', 'weight' => 1.0, 'zone' => 1, 'rate' => 100000.0, 'currency' => 'IRR', 'effective_at' => now()->subDay(), ]); // کد فعال ولی ظرفیتش پر شده — نباید در قیمت اعمال شود (سخت‌سازی) \App\Models\DiscountCode::create([ 'code' => 'FULL', 'type' => 'percentage', 'value' => 50, 'usage_limit' => 3, 'used_count' => 3, 'is_active' => true, ]); $service = app(PriceCalculatorService::class); $result = $service->calculate([ 'direction' => 'export', 'type' => 'DOC_NORMAL', 'country_iso' => 'AE', 'weight' => 1.0, 'volumetric_weight' => 0, 'extra_service' => 0, 'packing_cost' => 0, 'domestic_pickup' => 0, 'domestic_delivery' => 0, 'warehousing_cost' => 0, 'discount_code' => 'FULL', ]); $this->assertFalse($result['discount_applied']); $this->assertEquals(0, $result['discount_amount']); $this->assertEquals(100000, $result['total_fee']); } }