Introduce order management functionality including web routes for creating orders and a new API endpoint for price calculations. This change also cleans up the codebase by removing various debug scripts used during the development of the shipping rate logic. - Add `OrderController` to handle order creation and success redirection. - Add `POST /v1/calculate` endpoint for pricing calculations. - Define web routes for order creation flow (`/order`). - Remove multiple debug PHP scripts from the `04_Laravel` directory. - Add base layout and order view directories.
406 lines
25 KiB
PHP
406 lines
25 KiB
PHP
@extends('layouts.app')
|
||
|
||
@section('content')
|
||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-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 action="{{ route('orders.store') }}" method="POST" id="orderForm" class="p-6 space-y-8">
|
||
@csrf
|
||
|
||
<input type="hidden" name="direction" id="direction" value="export">
|
||
<input type="hidden" name="type" id="type" value="DOC_NORMAL">
|
||
|
||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
||
<div class="space-y-6">
|
||
<h2 class="text-lg font-semibold text-gray-900 border-b pb-2">اطلاعات مسیر</h2>
|
||
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-1">نوع سرویس</label>
|
||
<select id="serviceType" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500">
|
||
<option value="DOC_NORMAL" selected>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="directionSelect" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500">
|
||
<option value="export" selected>صادرات (از ایران)</option>
|
||
<option value="import">واردات (به ایران)</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="grid grid-cols-2 gap-4">
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-1">کشور مبدأ</label>
|
||
<select name="from_country_id" id="fromCountry" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500" required>
|
||
<option value="">انتخاب کنید</option>
|
||
@foreach($countries as $country)
|
||
<option value="{{ $country->id }}" data-iso="{{ $country->iso_code }}" {{ old('from_country_id') == $country->id ? 'selected' : '' }}>{{ $country->name }}</option>
|
||
@endforeach
|
||
</select>
|
||
</div>
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-1">کشور مقصد</label>
|
||
<select name="to_country_id" id="toCountry" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500" required>
|
||
<option value="">انتخاب کنید</option>
|
||
@foreach($countries as $country)
|
||
<option value="{{ $country->id }}" data-iso="{{ $country->iso_code }}" {{ old('to_country_id') == $country->id ? 'selected' : '' }}>{{ $country->name }}</option>
|
||
@endforeach
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-1">فراوئر</label>
|
||
<input type="text" name="forwarder" value="{{ old('forwarder') }}" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500" placeholder="مثال: DHL, FedEx">
|
||
</div>
|
||
|
||
<div class="grid grid-cols-2 gap-4">
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-1">وزن واقعی (kg)</label>
|
||
<input type="number" step="0.01" name="weight" id="weight" value="{{ old('weight') }}" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500" required>
|
||
</div>
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-1">وزن حجمی (kg)</label>
|
||
<input type="number" step="0.01" name="volumetric_weight" id="volumetricWeight" value="{{ old('volumetric_weight') }}" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500">
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-1">ابعاد (طول × عرض × ارتفاع به cm)</label>
|
||
<input type="text" name="dimensions" value="{{ old('dimensions') }}" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500" placeholder="مثال: 30×20×10">
|
||
</div>
|
||
|
||
<div id="spotRateWarning" class="hidden bg-yellow-50 border border-yellow-200 rounded-md p-4">
|
||
<p class="text-sm text-yellow-700">مرسولات بالای ۳۰ کیلوگرم نیاز به استعلام قیمت ویژه دارند. کارشناسان ما با شما تماس میگیرند.</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="space-y-6">
|
||
<h2 class="text-lg font-semibold text-gray-900 border-b pb-2">اطلاعات فرستنده</h2>
|
||
|
||
<div class="grid grid-cols-2 gap-4">
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-1">نام <span class="text-red-500">*</span></label>
|
||
<input type="text" name="sender_name" value="{{ old('sender_name') }}" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500" required>
|
||
</div>
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-1">شرکت</label>
|
||
<input type="text" name="sender_company" value="{{ old('sender_company') }}" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="grid grid-cols-2 gap-4">
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-1">تلفن <span class="text-red-500">*</span></label>
|
||
<input type="text" name="sender_phone" value="{{ old('sender_phone') }}" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500" required>
|
||
</div>
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-1">ایمیل</label>
|
||
<input type="email" name="sender_email" value="{{ old('sender_email') }}" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500">
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-1">آدرس <span class="text-red-500">*</span></label>
|
||
<input type="text" name="sender_address" value="{{ old('sender_address') }}" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500" required>
|
||
</div>
|
||
|
||
<div class="grid grid-cols-3 gap-4">
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-1">شهر <span class="text-red-500">*</span></label>
|
||
<input type="text" name="sender_city" value="{{ old('sender_city') }}" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500" required>
|
||
</div>
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-1">کد پستی</label>
|
||
<input type="text" name="sender_zip" value="{{ old('sender_zip') }}" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500">
|
||
</div>
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-1">شماره شناسنامه</label>
|
||
<input type="text" name="sender_id_number" value="{{ old('sender_id_number') }}" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="border-t border-gray-200 pt-8">
|
||
<h2 class="text-lg font-semibold text-gray-900 border-b pb-2 mb-6">اطلاعات گیرنده</h2>
|
||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
||
<div class="space-y-4">
|
||
<div class="grid grid-cols-2 gap-4">
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-1">نام <span class="text-red-500">*</span></label>
|
||
<input type="text" name="receiver_name" value="{{ old('receiver_name') }}" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500" required>
|
||
</div>
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-1">شرکت</label>
|
||
<input type="text" name="receiver_company" value="{{ old('receiver_company') }}" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="grid grid-cols-2 gap-4">
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-1">تلفن <span class="text-red-500">*</span></label>
|
||
<input type="text" name="receiver_phone" value="{{ old('receiver_phone') }}" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500" required>
|
||
</div>
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-1">ایمیل</label>
|
||
<input type="email" name="receiver_email" value="{{ old('receiver_email') }}" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500">
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-1">آدرس <span class="text-red-500">*</span></label>
|
||
<input type="text" name="receiver_address" value="{{ old('receiver_address') }}" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500" required>
|
||
</div>
|
||
|
||
<div class="grid grid-cols-3 gap-4">
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-1">شهر <span class="text-red-500">*</span></label>
|
||
<input type="text" name="receiver_city" value="{{ old('receiver_city') }}" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500" required>
|
||
</div>
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-1">کد پستی</label>
|
||
<input type="text" name="receiver_zip" value="{{ old('receiver_zip') }}" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500">
|
||
</div>
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-1">شماره شناسنامه</label>
|
||
<input type="text" name="receiver_id_number" value="{{ old('receiver_id_number') }}" class="w-full rounded-md border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="border-t border-gray-200 pt-8">
|
||
<div class="flex justify-between items-center mb-6">
|
||
<h2 class="text-lg font-semibold text-gray-900 border-b pb-2">کالاهای گمرکی</h2>
|
||
<button type="button" id="addItemBtn" class="inline-flex items-center px-4 py-2 bg-orange-600 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest 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>
|
||
|
||
<div class="overflow-x-auto">
|
||
<table class="min-w-full divide-y divide-gray-200 border border-gray-200 rounded-lg overflow-hidden">
|
||
<thead class="bg-gray-50">
|
||
<tr>
|
||
<th class="px-4 py-3 text-right text-xs font-medium text-gray-500 uppercase w-16">ردیف</th>
|
||
<th class="px-4 py-3 text-right text-xs font-medium text-gray-500 uppercase">شرح کالا</th>
|
||
<th class="px-4 py-3 text-right text-xs font-medium text-gray-500 uppercase w-32">کد HS</th>
|
||
<th class="px-4 py-3 text-right text-xs font-medium text-gray-500 uppercase w-24">تعداد</th>
|
||
<th class="px-4 py-3 text-right text-xs font-medium text-gray-500 uppercase w-32">قیمت واحد (USD)</th>
|
||
<th class="px-4 py-3 text-right text-xs font-medium text-gray-500 uppercase w-36">جمع (USD)</th>
|
||
<th class="px-4 py-3 text-center text-xs font-medium text-gray-500 uppercase w-20">عملیات</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="itemsTableBody" class="bg-white divide-y divide-gray-200">
|
||
<tr class="item-row">
|
||
<td class="px-4 py-3"><input type="text" value="1" readonly class="w-full rounded border-gray-300 bg-gray-100 text-center text-sm"></td>
|
||
<td class="px-4 py-3"><input type="text" name="items[0][description]" class="w-full rounded border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500 text-sm" placeholder="شرح کالا" required></td>
|
||
<td class="px-4 py-3"><input type="text" name="items[0][hs_code]" class="w-full rounded border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500 text-sm" placeholder="HS Code" required></td>
|
||
<td class="px-4 py-3"><input type="number" name="items[0][quantity]" class="w-full rounded border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500 text-sm qty-input" placeholder="1" min="1" required></td>
|
||
<td class="px-4 py-3"><input type="number" step="0.01" name="items[0][unit_price]" class="w-full rounded border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500 text-sm price-input" placeholder="0.00" min="0" required></td>
|
||
<td class="px-4 py-3"><input type="number" step="0.01" name="items[0][total_usd]" class="w-full rounded border-gray-300 bg-gray-50 text-left text-sm total-input" placeholder="0.00" readonly></td>
|
||
<td class="px-4 py-3 text-center"></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div class="mt-4 flex justify-end">
|
||
<div class="bg-gray-50 rounded-lg p-4 border border-gray-200">
|
||
<div class="text-sm text-gray-600">جمع کل فاکتور (USD):</div>
|
||
<div class="text-2xl font-bold text-gray-900" id="invoiceTotal">0.00</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="priceResult" class="hidden border-t border-gray-200 pt-8">
|
||
<h2 class="text-lg font-semibold text-gray-900 border-b pb-2 mb-6">قیمت محاسبه شده</h2>
|
||
<div class="bg-orange-50 border border-orange-200 rounded-lg p-6">
|
||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||
<div>
|
||
<div class="text-sm text-gray-600">قیمت پایه</div>
|
||
<div class="text-lg font-semibold" id="basePrice">—</div>
|
||
</div>
|
||
<div>
|
||
<div class="text-sm text-gray-600">قیمت نهایی (ریال)</div>
|
||
<div class="text-lg font-semibold text-orange-600" id="totalFee">—</div>
|
||
</div>
|
||
<div>
|
||
<div class="text-sm text-gray-600">زون</div>
|
||
<div class="text-lg font-semibold" id="zone">—</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="border-t border-gray-200 pt-6 flex justify-end">
|
||
<button type="submit" id="submitBtn" 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>
|
||
</div>
|
||
@endsection
|
||
|
||
@push('scripts')
|
||
<script>
|
||
let itemCount = 1;
|
||
const maxItems = 9;
|
||
|
||
function updateRowNumbers() {
|
||
document.querySelectorAll('.item-row').forEach((row, index) => {
|
||
row.querySelector('td:first-child input').value = index + 1;
|
||
row.querySelectorAll('input').forEach(input => {
|
||
if (input.name) {
|
||
input.name = input.name.replace(/items\[\d+\]/, `items[${index}]`);
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
function calculateRowTotal(row) {
|
||
const qty = parseFloat(row.querySelector('.qty-input').value) || 0;
|
||
const price = parseFloat(row.querySelector('.price-input').value) || 0;
|
||
const total = qty * price;
|
||
row.querySelector('.total-input').value = total.toFixed(2);
|
||
updateInvoiceTotal();
|
||
}
|
||
|
||
function updateInvoiceTotal() {
|
||
let total = 0;
|
||
document.querySelectorAll('.total-input').forEach(input => {
|
||
total += parseFloat(input.value) || 0;
|
||
});
|
||
document.getElementById('invoiceTotal').textContent = total.toFixed(2);
|
||
}
|
||
|
||
function addItemRow() {
|
||
if (itemCount >= maxItems) {
|
||
alert('حداکثر ۹ ردیف میتوانید اضافه کنید.');
|
||
return;
|
||
}
|
||
|
||
const tbody = document.getElementById('itemsTableBody');
|
||
const row = document.createElement('tr');
|
||
row.className = 'item-row';
|
||
row.innerHTML = `
|
||
<td class="px-4 py-3"><input type="text" value="${itemCount + 1}" readonly class="w-full rounded border-gray-300 bg-gray-100 text-center text-sm"></td>
|
||
<td class="px-4 py-3"><input type="text" name="items[${itemCount}][description]" class="w-full rounded border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500 text-sm" placeholder="شرح کالا" required></td>
|
||
<td class="px-4 py-3"><input type="text" name="items[${itemCount}][hs_code]" class="w-full rounded border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500 text-sm" placeholder="HS Code" required></td>
|
||
<td class="px-4 py-3"><input type="number" name="items[${itemCount}][quantity]" class="w-full rounded border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500 text-sm qty-input" placeholder="1" min="1" required></td>
|
||
<td class="px-4 py-3"><input type="number" step="0.01" name="items[${itemCount}][unit_price]" class="w-full rounded border-gray-300 shadow-sm focus:border-orange-500 focus:ring-orange-500 text-sm price-input" placeholder="0.00" min="0" required></td>
|
||
<td class="px-4 py-3"><input type="number" step="0.01" name="items[${itemCount}][total_usd]" class="w-full rounded border-gray-300 bg-gray-50 text-left text-sm total-input" placeholder="0.00" readonly></td>
|
||
<td class="px-4 py-3 text-center">
|
||
<button type="button" onclick="removeItemRow(this)" class="text-red-600 hover:text-red-800 text-sm">حذف</button>
|
||
</td>
|
||
`;
|
||
tbody.appendChild(row);
|
||
itemCount++;
|
||
|
||
row.querySelector('.qty-input').addEventListener('input', () => calculateRowTotal(row));
|
||
row.querySelector('.price-input').addEventListener('input', () => calculateRowTotal(row));
|
||
}
|
||
|
||
function removeItemRow(btn) {
|
||
const row = btn.closest('tr');
|
||
row.remove();
|
||
updateRowNumbers();
|
||
updateInvoiceTotal();
|
||
}
|
||
|
||
document.getElementById('addItemBtn').addEventListener('click', addItemRow);
|
||
|
||
document.querySelectorAll('.qty-input, .price-input').forEach(input => {
|
||
input.addEventListener('input', () => calculateRowTotal(input.closest('tr')));
|
||
});
|
||
|
||
async function calculatePrice() {
|
||
const direction = document.getElementById('directionSelect').value;
|
||
const type = document.getElementById('serviceType').value;
|
||
const fromCountry = document.getElementById('fromCountry').value;
|
||
const toCountry = document.getElementById('toCountry').value;
|
||
const weight = parseFloat(document.getElementById('weight').value) || 0;
|
||
const volumetricWeight = parseFloat(document.getElementById('volumetricWeight').value) || weight;
|
||
|
||
document.getElementById('direction').value = direction;
|
||
document.getElementById('type').value = type;
|
||
|
||
if (!fromCountry || !toCountry || weight <= 0) {
|
||
document.getElementById('priceResult').classList.add('hidden');
|
||
return;
|
||
}
|
||
|
||
if (weight > 30) {
|
||
document.getElementById('spotRateWarning').classList.remove('hidden');
|
||
document.getElementById('priceResult').classList.add('hidden');
|
||
return;
|
||
} else {
|
||
document.getElementById('spotRateWarning').classList.add('hidden');
|
||
}
|
||
|
||
const chargeableWeight = Math.max(weight, volumetricWeight);
|
||
const toCountryIso = document.getElementById('toCountry').selectedOptions[0]?.dataset?.iso || '';
|
||
|
||
try {
|
||
const response = await fetch('/api/v1/calculate', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
'Accept': 'application/json',
|
||
},
|
||
body: JSON.stringify({
|
||
direction: direction === 'export' ? 'Outbound' : 'Inbound',
|
||
type: type,
|
||
country_iso: toCountryIso,
|
||
weight: chargeableWeight,
|
||
volumetric_weight: chargeableWeight,
|
||
}),
|
||
});
|
||
|
||
const data = await response.json();
|
||
|
||
if (response.ok) {
|
||
document.getElementById('basePrice').textContent = data.base_price?.toFixed(2) + ' درهم';
|
||
document.getElementById('totalFee').textContent = Number(data.total_fee).toLocaleString('fa-IR') + ' ریال';
|
||
document.getElementById('zone').textContent = data.zone;
|
||
document.getElementById('priceResult').classList.remove('hidden');
|
||
} else {
|
||
document.getElementById('priceResult').classList.add('hidden');
|
||
}
|
||
} catch (error) {
|
||
console.error('Price calculation error:', error);
|
||
document.getElementById('priceResult').classList.add('hidden');
|
||
}
|
||
}
|
||
|
||
document.getElementById('directionSelect').addEventListener('change', calculatePrice);
|
||
document.getElementById('serviceType').addEventListener('change', calculatePrice);
|
||
document.getElementById('fromCountry').addEventListener('change', calculatePrice);
|
||
document.getElementById('toCountry').addEventListener('change', calculatePrice);
|
||
document.getElementById('weight').addEventListener('input', calculatePrice);
|
||
document.getElementById('volumetricWeight').addEventListener('input', calculatePrice);
|
||
|
||
document.getElementById('orderForm').addEventListener('submit', function(e) {
|
||
const itemCount = document.querySelectorAll('.item-row').length;
|
||
if (itemCount < 1) {
|
||
e.preventDefault();
|
||
alert('حداقل یک کالای گمرکی باید وارد شود.');
|
||
return;
|
||
}
|
||
|
||
document.querySelectorAll('.total-input').forEach((input, index) => {
|
||
input.name = `items[${index}][total_usd]`;
|
||
});
|
||
});
|
||
</script>
|
||
@endpush
|