Improve the reliability and usability of the shipping rates import process and update PDF document templates for better visual fidelity. - Enhance `ImportShippingRates` command with `--clear` and `--dry-run` options to prevent accidental data loss and allow safe testing. - Implement error handling and statistics tracking in `ShippingRatesImport` to capture skipped rows and import errors. - Refactor AWB and Label PDF templates to use A4 standard dimensions and improved CSS layouts. - Integrate company logo into PDF headers. - Add a new pricing inquiry page and navigation link. - Clean up obsolete test scripts.
143 lines
7.1 KiB
PHP
143 lines
7.1 KiB
PHP
@extends('layouts.app')
|
|
|
|
@section('content')
|
|
<div class="max-w-3xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
|
<div class="bg-white shadow rounded-lg">
|
|
<div class="px-6 py-5 border-b border-gray-200">
|
|
<h1 class="text-2xl font-bold text-gray-900">استعلام قیمت</h1>
|
|
<p class="mt-1 text-sm text-gray-500">قیمت تقریبی حمل مرسوله خود را محاسبه کنید</p>
|
|
</div>
|
|
|
|
<form id="pricingForm" class="p-6 space-y-6">
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">جهت ارسال</label>
|
|
<select id="direction" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500">
|
|
<option value="Outbound">صادرات (از ایران)</option>
|
|
<option value="Inbound">واردات (به ایران)</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">نوع سرویس</label>
|
|
<select id="type" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500">
|
|
<option value="DOC_NORMAL">Document Normal</option>
|
|
<option value="DOC_ECONOMY">Document Economy</option>
|
|
<option value="PARCEL">Parcel</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">کشور مقصد</label>
|
|
<select id="country" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500">
|
|
<option value="">انتخاب کنید</option>
|
|
@foreach($countries as $country)
|
|
<option value="{{ $country->iso_code }}">{{ $country->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">وزن قابل پرداخت (kg)</label>
|
|
<input type="number" step="0.01" id="weight" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500" placeholder="مثال: 1.5" required>
|
|
</div>
|
|
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">وزن حجمی (kg)</label>
|
|
<input type="number" step="0.01" id="volumetricWeight" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500" placeholder="در صورت عدم اطلاع، خالی بگذارید">
|
|
</div>
|
|
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">سرویس اضافی (AED)</label>
|
|
<input type="number" step="0.01" id="extraService" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500" placeholder="اختیاری">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex justify-end">
|
|
<button type="submit" class="inline-flex items-center px-6 py-3 bg-orange-600 border border-transparent rounded-md font-semibold text-white hover:bg-orange-700 focus:bg-orange-700 active:bg-orange-900 focus:outline-none focus:ring-2 focus:ring-orange-500 focus:ring-offset-2 transition ease-in-out duration-150">
|
|
محاسبه قیمت
|
|
</button>
|
|
</div>
|
|
</form>
|
|
|
|
<div id="result" class="hidden px-6 pb-6">
|
|
<div class="bg-orange-50 border border-orange-200 rounded-lg p-6">
|
|
<h3 class="text-lg font-semibold text-gray-900 mb-4">نتیجه محاسبه</h3>
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div>
|
|
<span class="text-sm text-gray-600">قیمت پایه (AED)</span>
|
|
<div class="text-xl font-bold" id="basePrice">—</div>
|
|
</div>
|
|
<div>
|
|
<span class="text-sm text-gray-600">قیمت نهایی (IRR)</span>
|
|
<div class="text-xl font-bold text-orange-600" id="totalFee">—</div>
|
|
</div>
|
|
<div>
|
|
<span class="text-sm text-gray-600">زون</span>
|
|
<div class="text-xl font-bold" id="zone">—</div>
|
|
</div>
|
|
<div>
|
|
<span class="text-sm text-gray-600">نرخ تبدیل</span>
|
|
<div class="text-xl font-bold" id="rate">—</div>
|
|
</div>
|
|
</div>
|
|
<p class="text-xs text-gray-500 mt-4">* این قیمت تقریبی است و نهایی بودن آن منوط تأیید کارشناسان خواهد بود.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endsection
|
|
|
|
@push('scripts')
|
|
<script>
|
|
document.getElementById('pricingForm').addEventListener('submit', async function(e) {
|
|
e.preventDefault();
|
|
|
|
const direction = document.getElementById('direction').value;
|
|
const type = document.getElementById('type').value;
|
|
const country = document.getElementById('country').value;
|
|
const weight = parseFloat(document.getElementById('weight').value) || 0;
|
|
const volumetricWeight = parseFloat(document.getElementById('volumetricWeight').value) || weight;
|
|
|
|
if (!country || weight <= 0) {
|
|
alert('لطفاً کشور مقصد و وزن را وارد کنید.');
|
|
return;
|
|
}
|
|
|
|
const chargeableWeight = Math.max(weight, volumetricWeight);
|
|
|
|
try {
|
|
const response = await fetch('/api/v1/calculate', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
direction: direction,
|
|
type: type,
|
|
country_iso: country,
|
|
weight: chargeableWeight,
|
|
volumetric_weight: chargeableWeight,
|
|
}),
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (response.ok) {
|
|
document.getElementById('basePrice').textContent = Number(data.base_price).toFixed(2) + ' درهم';
|
|
document.getElementById('totalFee').textContent = Number(data.total_fee).toLocaleString('fa-IR') + ' ریال';
|
|
document.getElementById('zone').textContent = data.zone;
|
|
document.getElementById('rate').textContent = '1 درهم = {{ number_format($settings['aed_to_irr'], 0) }} ریال';
|
|
document.getElementById('result').classList.remove('hidden');
|
|
} else {
|
|
alert('خطا در محاسبه قیمت. لطفاً دوباره تلاش کنید.');
|
|
}
|
|
} catch (error) {
|
|
console.error('Error:', error);
|
|
alert('خطا در ارتباط با سرور.');
|
|
}
|
|
});
|
|
</script>
|
|
@endpush
|