Compare commits
2 Commits
02c29db696
...
b25bfda597
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b25bfda597 | ||
|
|
eda3110ac1 |
@ -153,8 +153,8 @@
|
||||
}
|
||||
.ifnex-step.active { color: var(--ifnex-primary-dark); font-weight: 700; }
|
||||
|
||||
.ifnex-form-step { display: none; }
|
||||
.ifnex-form-step.active { display: block; animation: ifnexFadeIn 0.3s; }
|
||||
.ifnex-form-step { display: none !important; }
|
||||
.ifnex-form-step.active { display: block !important; }
|
||||
@keyframes ifnexFadeIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; } }
|
||||
|
||||
.ifnex-form-card {
|
||||
@ -374,14 +374,14 @@
|
||||
|
||||
/* ═══ Modern Customer Dashboard (ifnx) ═══ */
|
||||
.ifnx-dashboard {
|
||||
display: flex; gap: 24px; max-width: 1240px; margin: 0 auto; padding: 24px 0;
|
||||
display: flex !important; gap: 24px; max-width: 1240px; margin: 0 auto; padding: 24px 0;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
/* ── Sidebar ─ */
|
||||
.ifnx-sidebar {
|
||||
width: 260px; flex-shrink: 0; align-self: flex-start;
|
||||
background: linear-gradient(180deg, #0f172a 0%, #1e293b 100%);
|
||||
width: 260px !important; flex-shrink: 0 !important; align-self: flex-start !important;
|
||||
background: linear-gradient(180deg, #0f172a 0%, #1e293b 100%) !important;
|
||||
border-radius: 20px; overflow: hidden;
|
||||
box-shadow: 0 10px 30px rgba(15, 23, 42, 0.25);
|
||||
}
|
||||
@ -395,7 +395,7 @@
|
||||
.ifnx-user-name { color: #fff; font-weight: 700; font-size: 16px; }
|
||||
.ifnx-user-email { color: rgba(255,255,255,0.55); font-size: 12px; margin-top: 4px; direction: ltr; }
|
||||
|
||||
.ifnx-menu { padding: 12px 0; display: flex; flex-direction: column; }
|
||||
.ifnx-menu { padding: 12px 0; display: flex !important; flex-direction: column !important; }
|
||||
.ifnx-menu-item {
|
||||
display: flex; align-items: center; gap: 12px;
|
||||
padding: 13px 22px; color: rgba(255,255,255,0.72);
|
||||
|
||||
@ -10,20 +10,38 @@ jQuery(document).ready(function($) {
|
||||
|
||||
// ─── Load Countries ───
|
||||
function loadCountries() {
|
||||
if (!ifnex_ajax || !ifnex_ajax.ajax_url) {
|
||||
console.error('IFNEX: ifnex_ajax is not defined');
|
||||
showFormError('خطا در تنظیمات پلاگین. لطفاً صفحه را دوباره بارگذاری کنید.');
|
||||
return;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: ifnex_ajax.ajax_url,
|
||||
method: 'POST',
|
||||
data: { action: 'ifnex_get_countries', nonce: ifnex_ajax.nonce },
|
||||
success: function(res) {
|
||||
if (res.success) {
|
||||
if (res.success && res.data && res.data.length > 0) {
|
||||
countries = res.data;
|
||||
populateCountrySelects();
|
||||
// Auto-select Iran based on default direction
|
||||
var iran = countries.find(function(c) { return c.iso_code === 'IR'; });
|
||||
if (iran) {
|
||||
var dir = $('#ifnex-direction').val();
|
||||
if (dir === 'export') {
|
||||
$('#ifnex-from-country').val(iran.id).trigger('change');
|
||||
} else if (dir === 'import') {
|
||||
$('#ifnex-to-country').val(iran.id).trigger('change');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.error('IFNEX: Failed to load countries', res);
|
||||
showFormError('خطا در دریافت لیست کشورها. لطفاً صفحه را دوباره بارگذاری کنید.');
|
||||
}
|
||||
},
|
||||
error: function(xhr) {
|
||||
console.error('IFNEX: AJAX error loading countries', xhr.status);
|
||||
showFormError('خطا در ارتباط با سرور. لطفاً اینترنت خود را بررسی کنید.');
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -166,26 +184,26 @@ jQuery(document).ready(function($) {
|
||||
|
||||
// وزن واقعی
|
||||
html += '<div class="ifnex-field">';
|
||||
html += '<label>وزن واقعی (kg) *</label>';
|
||||
html += '<input type="number" class="ifnex-pkg-weight" step="0.1" min="0.1" data-pkg-id="' + pkg.id + '" placeholder="مثلاً 2.5" value="' + (pkg.weight || '') + '" required>';
|
||||
html += '<label for="ifnex-pkg-weight-' + pkg.id + '">وزن واقعی (kg) *</label>';
|
||||
html += '<input type="number" id="ifnex-pkg-weight-' + pkg.id + '" class="ifnex-pkg-weight" name="packages[' + pkg.number + '][weight]" step="0.1" min="0.1" data-pkg-id="' + pkg.id + '" placeholder="مثلاً 2.5" value="' + (pkg.weight || '') + '" required>';
|
||||
html += '</div>';
|
||||
|
||||
// ابعاد
|
||||
html += '<div class="ifnex-field">';
|
||||
html += '<label>ابعاد (طول×عرض×ارتفاع cm) *</label>';
|
||||
html += '<input type="text" class="ifnex-pkg-dimensions" data-pkg-id="' + pkg.id + '" placeholder="مثلاً 5*6*9" value="' + (pkg.dimensions || '') + '" style="direction: ltr;" required>';
|
||||
html += '<label for="ifnex-pkg-dimensions-' + pkg.id + '">ابعاد (طول×عرض×ارتفاع cm) *</label>';
|
||||
html += '<input type="text" id="ifnex-pkg-dimensions-' + pkg.id + '" class="ifnex-pkg-dimensions" name="packages[' + pkg.number + '][dimensions]" data-pkg-id="' + pkg.id + '" placeholder="مثلاً 5*6*9" value="' + (pkg.dimensions || '') + '" style="direction: ltr;" required>';
|
||||
html += '</div>';
|
||||
|
||||
// وزن حجمی (محاسبه خودکار - فقط نمایش)
|
||||
html += '<div class="ifnex-field">';
|
||||
html += '<label>وزن حجمی (kg)</label>';
|
||||
html += '<input type="text" class="ifnex-pkg-volumetric-display" data-pkg-id="' + pkg.id + '" value="0" readonly style="background: #f0f9ff; color: #0369a1; font-weight: bold;">';
|
||||
html += '<label for="ifnex-pkg-volumetric-' + pkg.id + '">وزن حجمی (kg)</label>';
|
||||
html += '<input type="text" id="ifnex-pkg-volumetric-' + pkg.id + '" class="ifnex-pkg-volumetric-display" name="packages[' + pkg.number + '][volumetric_weight]" data-pkg-id="' + pkg.id + '" value="0" readonly style="background: #f0f9ff; color: #0369a1; font-weight: bold;">';
|
||||
html += '</div>';
|
||||
|
||||
// توضیحات
|
||||
html += '<div class="ifnex-field full">';
|
||||
html += '<label>توضیحات بسته (اختیاری)</label>';
|
||||
html += '<input type="text" class="ifnex-pkg-description" data-pkg-id="' + pkg.id + '" placeholder="مثلاً کتاب، لباس، اسباببازی..." value="' + (pkg.description || '') + '">';
|
||||
html += '<label for="ifnex-pkg-desc-' + pkg.id + '">توضیحات بسته (اختیاری)</label>';
|
||||
html += '<input type="text" id="ifnex-pkg-desc-' + pkg.id + '" class="ifnex-pkg-description" name="packages[' + pkg.number + '][description]" data-pkg-id="' + pkg.id + '" placeholder="مثلاً کتاب، لباس، اسباببازی..." value="' + (pkg.description || '') + '">';
|
||||
html += '</div>';
|
||||
|
||||
html += '</div>';
|
||||
@ -327,32 +345,32 @@ jQuery(document).ready(function($) {
|
||||
|
||||
// توضیحات
|
||||
html += '<div class="ifnex-field full">';
|
||||
html += '<label>شرح کالا *</label>';
|
||||
html += '<input type="text" class="ifnex-item-description" data-item-id="' + item.id + '" placeholder="مثلاً Electronics PCB Board" value="' + (item.description || '') + '" required style="direction: ltr;">';
|
||||
html += '<label for="ifnex-item-desc-' + item.id + '">شرح کالا *</label>';
|
||||
html += '<input type="text" id="ifnex-item-desc-' + item.id + '" class="ifnex-item-description" name="items[' + item.number + '][description]" data-item-id="' + item.id + '" placeholder="مثلاً Electronics PCB Board" value="' + (item.description || '') + '" required style="direction: ltr;">';
|
||||
html += '</div>';
|
||||
|
||||
// HS Code
|
||||
html += '<div class="ifnex-field">';
|
||||
html += '<label>کد گمرکی (HS Code) *</label>';
|
||||
html += '<input type="text" class="ifnex-item-hs-code" data-item-id="' + item.id + '" placeholder="مثلاً 8542390001" value="' + (item.hsCode || '') + '" required style="direction: ltr;">';
|
||||
html += '<label for="ifnex-item-hs-' + item.id + '">کد گمرکی (HS Code) *</label>';
|
||||
html += '<input type="text" id="ifnex-item-hs-' + item.id + '" class="ifnex-item-hs-code" name="items[' + item.number + '][hs_code]" data-item-id="' + item.id + '" placeholder="مثلاً 8542390001" value="' + (item.hsCode || '') + '" required style="direction: ltr;">';
|
||||
html += '</div>';
|
||||
|
||||
// تعداد
|
||||
html += '<div class="ifnex-field">';
|
||||
html += '<label>تعداد *</label>';
|
||||
html += '<input type="number" class="ifnex-item-quantity" data-item-id="' + item.id + '" min="1" step="1" placeholder="مثلاً 100" value="' + (item.quantity || '') + '" required>';
|
||||
html += '<label for="ifnex-item-qty-' + item.id + '">تعداد *</label>';
|
||||
html += '<input type="number" id="ifnex-item-qty-' + item.id + '" class="ifnex-item-quantity" name="items[' + item.number + '][quantity]" min="1" step="1" data-item-id="' + item.id + '" placeholder="مثلاً 100" value="' + (item.quantity || '') + '" required>';
|
||||
html += '</div>';
|
||||
|
||||
// قیمت واحد
|
||||
html += '<div class="ifnex-field">';
|
||||
html += '<label>قیمت واحد (USD) *</label>';
|
||||
html += '<input type="number" class="ifnex-item-unit-price" data-item-id="' + item.id + '" min="0" step="0.01" placeholder="مثلاً 1.10" value="' + (item.unitPrice || '') + '" required style="direction: ltr;">';
|
||||
html += '<label for="ifnex-item-price-' + item.id + '">قیمت واحد (USD) *</label>';
|
||||
html += '<input type="number" id="ifnex-item-price-' + item.id + '" class="ifnex-item-unit-price" name="items[' + item.number + '][unit_price]" min="0" step="0.01" data-item-id="' + item.id + '" placeholder="مثلاً 1.10" value="' + (item.unitPrice || '') + '" required style="direction: ltr;">';
|
||||
html += '</div>';
|
||||
|
||||
// مجموع (محاسبه خودکار)
|
||||
html += '<div class="ifnex-field">';
|
||||
html += '<label>مجموع (USD)</label>';
|
||||
html += '<input type="text" class="ifnex-item-total-display" data-item-id="' + item.id + '" value="0.00" readonly style="background: #f0f9ff; color: #0369a1; font-weight: bold;">';
|
||||
html += '<input type="text" id="ifnex-item-total-' + item.id + '" class="ifnex-item-total-display" name="items[' + item.number + '][total]" data-item-id="' + item.id + '" value="0.00" readonly style="background: #f0f9ff; color: #0369a1; font-weight: bold;">';
|
||||
html += '</div>';
|
||||
|
||||
html += '</div>';
|
||||
@ -448,15 +466,15 @@ jQuery(document).ready(function($) {
|
||||
function updateInvoiceStepVisibility() {
|
||||
var type = $('#ifnex-type').val();
|
||||
if (type === 'PARCEL') {
|
||||
$('.ifnex-step-invoice').show();
|
||||
$('.ifnex-step-invoice-content').show();
|
||||
$('.ifnex-step-invoice').css('display', '');
|
||||
$('.ifnex-step-invoice-content').each(function() { this.style.setProperty('display', '', 'important'); });
|
||||
// اگه اقلام خالی هست، یه قلم اولیه اضافه کن
|
||||
if (invoiceItems.length === 0) {
|
||||
addInvoiceItem();
|
||||
}
|
||||
} else {
|
||||
$('.ifnex-step-invoice').hide();
|
||||
$('.ifnex-step-invoice-content').hide();
|
||||
$('.ifnex-step-invoice').css('display', 'none');
|
||||
$('.ifnex-step-invoice-content').each(function() { this.style.setProperty('display', 'none', 'important'); });
|
||||
// اگه کاربر توی Step 3 بود و نوع رو تغییر داد
|
||||
if (currentStep === 3) {
|
||||
goToStep(2);
|
||||
@ -498,16 +516,24 @@ jQuery(document).ready(function($) {
|
||||
}
|
||||
|
||||
// ─── Step Navigation ───
|
||||
// مراحل فرم خواهر هستند و فقط با کلاس active نمایش داده میشوند (CSS داخل ifnex-orders.css)
|
||||
function goToStep(step) {
|
||||
currentStep = step;
|
||||
$('.ifnex-form-step').removeClass('active');
|
||||
$('.ifnex-form-step[data-step="' + step + '"]').addClass('active');
|
||||
$('.ifnex-step').each(function() {
|
||||
var s = parseInt($(this).data('step'));
|
||||
$(this).toggleClass('active', s === step);
|
||||
$(this).toggleClass('done', s < step);
|
||||
var $steps = $('#ifnex-order-form .ifnex-form-step');
|
||||
$steps.removeClass('active');
|
||||
$steps.filter('[data-step="' + step + '"]').addClass('active');
|
||||
|
||||
// بهروزرسانی نشانگرهای پیشرفت بالای فرم
|
||||
$('.ifnex-steps .ifnex-step').each(function() {
|
||||
var s = parseInt($(this).attr('data-step'), 10);
|
||||
$(this).removeClass('active done');
|
||||
if (s === step) $(this).addClass('active');
|
||||
else if (s < step) $(this).addClass('done');
|
||||
});
|
||||
$('.ifnex-order-form-container')[0].scrollIntoView({ behavior: 'smooth' });
|
||||
|
||||
try {
|
||||
document.querySelector('.ifnex-order-form-container').scrollIntoView({ behavior: 'smooth' });
|
||||
} catch(e) {}
|
||||
}
|
||||
|
||||
$('.ifnex-next-step').on('click', function() {
|
||||
@ -574,12 +600,15 @@ jQuery(document).ready(function($) {
|
||||
|
||||
function validateStep2() {
|
||||
var ok = true;
|
||||
var persianRegex = /[\u0600-\u06FF]/;
|
||||
['#ifnex-sender-name', '#ifnex-sender-phone', '#ifnex-sender-city', '#ifnex-sender-address',
|
||||
'#ifnex-receiver-name', '#ifnex-receiver-phone', '#ifnex-receiver-city', '#ifnex-receiver-address'].forEach(function(sel) {
|
||||
if (!$(sel).val()) { $(sel).css('border-color', '#ef4444'); ok = false; }
|
||||
var val = $(sel).val();
|
||||
if (!val) { $(sel).css('border-color', '#ef4444'); ok = false; }
|
||||
else if (persianRegex.test(val)) { $(sel).css('border-color', '#ef4444'); ok = false; }
|
||||
else { $(sel).css('border-color', ''); }
|
||||
});
|
||||
if (!ok) showFormError('لطفاً اطلاعات فرستنده و گیرنده را کامل کنید.');
|
||||
if (!ok) showFormError('لطفاً اطلاعات را به انگلیسی وارد کنید. آدرس و مشخصات باید به انگلیسی باشد.');
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -599,7 +628,7 @@ jQuery(document).ready(function($) {
|
||||
if (res.success) {
|
||||
priceData = res.data;
|
||||
renderPriceSummary(res.data);
|
||||
goToStep(4);
|
||||
goToStep(5);
|
||||
} else {
|
||||
showCalcError(res.data || 'خطا در محاسبه قیمت');
|
||||
}
|
||||
@ -733,7 +762,7 @@ jQuery(document).ready(function($) {
|
||||
var orderId = res.data.data.id || res.data.id;
|
||||
// با فلوی جدید، کاربر به صفحه جزئیات سفارش هدایت میشود
|
||||
// (چون پرداخت فقط بعد از تأیید کارمند امکانپذیر است)
|
||||
window.location.href = ifnex_ajax.orders_url + 'order-detail/?order_id=' + orderId;
|
||||
window.location.href = ifnex_ajax.orders_url + '?tab=orders';
|
||||
} else {
|
||||
$('#ifnex-submit-error').text(res.data || 'خطا در ثبت سفارش').show();
|
||||
}
|
||||
@ -745,13 +774,26 @@ jQuery(document).ready(function($) {
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Auto-select Iran based on direction ───
|
||||
$('#ifnex-direction').on('change', function() {
|
||||
var direction = $(this).val();
|
||||
if (!countries.length) return;
|
||||
var iran = countries.find(function(c) { return c.iso_code === 'IR'; });
|
||||
if (!iran) return;
|
||||
if (direction === 'export') {
|
||||
$('#ifnex-from-country').val(iran.id).trigger('change');
|
||||
} else if (direction === 'import') {
|
||||
$('#ifnex-to-country').val(iran.id).trigger('change');
|
||||
}
|
||||
});
|
||||
|
||||
// ─── Init ───
|
||||
if ($('#ifnex-order-form').length) {
|
||||
loadCountries();
|
||||
// افزودن بسته اول بهصورت پیشفرض
|
||||
// افزودن بسته اول بهصورت پیشفرض (قبل از loadCountries تا اگه خطا داد، بسته باشه)
|
||||
addPackage();
|
||||
// بررسی نوع محموله برای نمایش/مخفیکردن Step Invoice
|
||||
// این تابع خودش اگه PARCEL باشه و اقلام خالی باشه، یه قلم اضافه میکنه
|
||||
updateInvoiceStepVisibility();
|
||||
// لود کشورها (اگه خطا داد اشکالی نداره)
|
||||
try { loadCountries(); } catch(e) { console.error('IFNEX: loadCountries error', e); }
|
||||
}
|
||||
});
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
if (function_exists('opcache_reset')) { @opcache_reset(); }
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Pragma: no-cache');
|
||||
/**
|
||||
* Plugin Name: IFNEX Logistics Bridge
|
||||
* Description: اتصال فرانتاند سایت ایفنکس به API لاراول
|
||||
@ -16,7 +19,7 @@ require_once plugin_dir_path( __FILE__ ) . 'includes/user-bridge.php';
|
||||
require_once plugin_dir_path( __FILE__ ) . 'includes/shortcodes.php';
|
||||
require_once plugin_dir_path( __FILE__ ) . 'includes/tracking-form.php';
|
||||
|
||||
// لود کردن استایلهای پلاگین
|
||||
// لود کردن استایلهای و اسکریپتهای پلاگین
|
||||
add_action('wp_enqueue_scripts', 'ifnex_enqueue_scripts');
|
||||
function ifnex_enqueue_scripts() {
|
||||
global $post;
|
||||
@ -24,8 +27,15 @@ function ifnex_enqueue_scripts() {
|
||||
(has_shortcode($post->post_content, 'ifnex_tracking_form') ||
|
||||
has_shortcode($post->post_content, 'ifnex_wallet_balance') ||
|
||||
has_shortcode($post->post_content, 'ifnex_transactions') ||
|
||||
has_shortcode($post->post_content, 'ifnex_tracking_status'))) {
|
||||
wp_enqueue_style('ifnex-bridge-css', plugin_dir_url(__FILE__) . 'assets/css/ifnex-bridge.css', array(), '1.0.0');
|
||||
has_shortcode($post->post_content, 'ifnex_tracking_status') ||
|
||||
has_shortcode($post->post_content, 'ifnex_order_form') ||
|
||||
has_shortcode($post->post_content, 'ifnex_user_profile') ||
|
||||
has_shortcode($post->post_content, 'ifnex_orders_list') ||
|
||||
has_shortcode($post->post_content, 'ifnex_order_detail') ||
|
||||
has_shortcode($post->post_content, 'ifnex_order_payment') ||
|
||||
has_shortcode($post->post_content, 'ifnex_customer_dashboard'))) {
|
||||
wp_enqueue_style('ifnex-bridge-css', plugin_dir_url(__FILE__) . 'assets/css/ifnex-bridge.css', array('ifnex-main'), '2.0.0-' . time());
|
||||
wp_enqueue_script('ifnex-order-form-js', plugin_dir_url(__FILE__) . 'assets/js/ifnex-order-form.js', array('jquery'), '2.0.0-' . time(), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
if (function_exists('opcache_reset')) { @opcache_reset(); }
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Pragma: no-cache');
|
||||
/**
|
||||
* IFNEX API Client
|
||||
* اتصال به API لاراول برای استعلام ترکینگ
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
if (function_exists('opcache_reset')) { @opcache_reset(); }
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Pragma: no-cache');
|
||||
/**
|
||||
* IFNEX Shortcodes
|
||||
* شورتکدهای پلاگین IFNEX Bridge
|
||||
@ -18,13 +21,16 @@ function ifnex_tracking_form_shortcode($atts) {
|
||||
'button_text' => 'رهگیری',
|
||||
), $atts);
|
||||
|
||||
// خواندن پارامتر awb از URL
|
||||
$awb_from_url = isset($_GET['awb']) ? sanitize_text_field($_GET['awb']) : '';
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<div class="ifnex-tracking-container">
|
||||
<h2><?php echo esc_html($atts['title']); ?></h2>
|
||||
<form id="ifnex-tracking-form" class="ifnex-tracking-form">
|
||||
<div class="ifnex-form-group">
|
||||
<input type="text" id="ifnex-awb-input" placeholder="<?php echo esc_attr($atts['placeholder']); ?>" required>
|
||||
<input type="text" id="ifnex-awb-input" placeholder="<?php echo esc_attr($atts['placeholder']); ?>" value="<?php echo esc_attr($awb_from_url); ?>" required>
|
||||
<button type="submit" id="ifnex-track-btn"><?php echo esc_html($atts['button_text']); ?></button>
|
||||
</div>
|
||||
</form>
|
||||
@ -537,28 +543,29 @@ function ifnex_order_form_shortcode($atts) {
|
||||
<h3>📦 مشخصات مرسوله</h3>
|
||||
<div class="ifnex-form-grid">
|
||||
<div class="ifnex-field">
|
||||
<label>جهت ارسال *</label>
|
||||
<select id="ifnex-direction">
|
||||
<label for="ifnex-direction">جهت ارسال *</label>
|
||||
<select id="ifnex-direction" name="ifnex_direction">
|
||||
<option value="export">صادرات (از ایران به خارج)</option>
|
||||
<option value="import">واردات (از خارج به ایران)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="ifnex-field">
|
||||
<label>نوع سرویس *</label>
|
||||
<select id="ifnex-type">
|
||||
<label for="ifnex-type">نوع سرویس *</label>
|
||||
<select id="ifnex-type" name="ifnex_type">
|
||||
<option value="PARCEL">بسته (Parcel)</option>
|
||||
<option value="DOC_NORMAL">مدارک عادی</option>
|
||||
<option value="DOC_ECONOMY">مدارک اقتصادی</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="ifnex-field">
|
||||
<label>کشور مبدأ *</label>
|
||||
<select id="ifnex-from-country"></select>
|
||||
<label for="ifnex-from-country">کشور مبدأ *</label>
|
||||
<select id="ifnex-from-country" name="ifnex_from_country"></select>
|
||||
</div>
|
||||
<div class="ifnex-field">
|
||||
<label>کشور مقصد *</label>
|
||||
<select id="ifnex-to-country"></select>
|
||||
<label for="ifnex-to-country">کشور مقصد *</label>
|
||||
<select id="ifnex-to-country" name="ifnex_to_country"></select>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ─── بخش بستهها (Multi-Package) ─── -->
|
||||
<h3 style="margin-top: 24px;">📦 بستههای مرسوله</h3>
|
||||
<p style="font-size: 12px; color: #666; margin-bottom: 12px;">
|
||||
@ -602,17 +609,17 @@ function ifnex_order_form_shortcode($atts) {
|
||||
<div class="ifnex-form-card">
|
||||
<h3>👤 اطلاعات فرستنده</h3>
|
||||
<div class="ifnex-form-grid">
|
||||
<div class="ifnex-field"><label>نام و نام خانوادگی *</label><input type="text" id="ifnex-sender-name"></div>
|
||||
<div class="ifnex-field"><label>شماره تماس *</label><input type="tel" id="ifnex-sender-phone"></div>
|
||||
<div class="ifnex-field"><label>شهر</label><input type="text" id="ifnex-sender-city"></div>
|
||||
<div class="ifnex-field full"><label>آدرس کامل *</label><textarea id="ifnex-sender-address" rows="2"></textarea></div>
|
||||
<div class="ifnex-field"><label for="ifnex-sender-name">نام و نام خانوادگی *</label><input type="text" id="ifnex-sender-name" name="ifnex_sender_name"></div>
|
||||
<div class="ifnex-field"><label for="ifnex-sender-phone">شماره تماس *</label><input type="tel" id="ifnex-sender-phone" name="ifnex_sender_phone"></div>
|
||||
<div class="ifnex-field"><label for="ifnex-sender-city">شهر</label><input type="text" id="ifnex-sender-city" name="ifnex_sender_city"></div>
|
||||
<div class="ifnex-field full"><label for="ifnex-sender-address">آدرس کامل *</label><textarea id="ifnex-sender-address" name="ifnex_sender_address" rows="2"></textarea></div>
|
||||
</div>
|
||||
<h3 style="margin-top:24px;">📮 اطلاعات گیرنده</h3>
|
||||
<div class="ifnex-form-grid">
|
||||
<div class="ifnex-field"><label>نام و نام خانوادگی *</label><input type="text" id="ifnex-receiver-name"></div>
|
||||
<div class="ifnex-field"><label>شماره تماس *</label><input type="tel" id="ifnex-receiver-phone"></div>
|
||||
<div class="ifnex-field"><label>شهر</label><input type="text" id="ifnex-receiver-city"></div>
|
||||
<div class="ifnex-field full"><label>آدرس کامل *</label><textarea id="ifnex-receiver-address" rows="2"></textarea></div>
|
||||
<div class="ifnex-field"><label for="ifnex-receiver-name">نام و نام خانوادگی *</label><input type="text" id="ifnex-receiver-name" name="ifnex_receiver_name"></div>
|
||||
<div class="ifnex-field"><label for="ifnex-receiver-phone">شماره تماس *</label><input type="tel" id="ifnex-receiver-phone" name="ifnex_receiver_phone"></div>
|
||||
<div class="ifnex-field"><label for="ifnex-receiver-city">شهر</label><input type="text" id="ifnex-receiver-city" name="ifnex_receiver_city"></div>
|
||||
<div class="ifnex-field full"><label for="ifnex-receiver-address">آدرس کامل *</label><textarea id="ifnex-receiver-address" name="ifnex_receiver_address" rows="2"></textarea></div>
|
||||
</div>
|
||||
<div class="ifnex-form-nav">
|
||||
<button class="ifnex-btn ifnex-prev-step">→ قبلی</button>
|
||||
@ -661,7 +668,7 @@ function ifnex_order_form_shortcode($atts) {
|
||||
<div class="ifnex-form-card">
|
||||
<h3>🏷️ کد تخفیف (اختیاری)</h3>
|
||||
<div class="ifnex-form-grid">
|
||||
<div class="ifnex-field full"><label>کد تخفیف</label><input type="text" id="ifnex-discount-code" placeholder="مثلاً WELCOME10"></div>
|
||||
<div class="ifnex-field full"><label for="ifnex-discount-code">کد تخفیف</label><input type="text" id="ifnex-discount-code" name="ifnex_discount_code" placeholder="مثلاً WELCOME10"></div>
|
||||
</div>
|
||||
<div id="ifnex-calc-error" class="ifnex-error-box" style="display:none;"></div>
|
||||
<div id="ifnex-calc-loading" style="display:none; text-align:center; padding:20px;">
|
||||
@ -742,12 +749,37 @@ function ifnex_order_payment_shortcode($atts) {
|
||||
$wallet_balance = is_wp_error($balance) ? 0 : ($balance['balance'] ?? 0);
|
||||
$can_pay_wallet = $wallet_balance >= $data['total_fee'];
|
||||
|
||||
// بررسی نتیجه پرداخت از درگاه (callback)
|
||||
$payment_status = sanitize_text_field($_GET['status'] ?? '');
|
||||
$payment_message = sanitize_text_field($_GET['message'] ?? '');
|
||||
$payment_ref_id = sanitize_text_field($_GET['ref_id'] ?? '');
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<div class="ifnex-payment-page">
|
||||
<div class="ifnex-payment-card">
|
||||
<h2>💳 پرداخت سفارش</h2>
|
||||
|
||||
<?php if ($payment_status === 'success'): ?>
|
||||
<div class="ifnex-success-box">
|
||||
<h3>✅ پرداخت با موفقیت انجام شد!</h3>
|
||||
<p>کد پیگیری تراکنش: <strong><?php echo esc_html($payment_ref_id); ?></strong></p>
|
||||
<p>مبلغ: <strong><?php echo number_format($data['total_fee']); ?> ریال</strong></p>
|
||||
<p>سفارش شما در حال پردازش است.</p>
|
||||
<a href="<?php echo esc_url(home_url('/my-orders/')); ?>" class="ifnex-btn ifnex-btn-primary">مشاهده سفارشات</a>
|
||||
</div>
|
||||
<?php elseif ($payment_status === 'failed'): ?>
|
||||
<div class="ifnex-error-box">
|
||||
<h3>❌ پرداخت ناموفق بود</h3>
|
||||
<p><?php echo esc_html($payment_message ?: 'پرداخت با خطا مواجه شد. لطفاً دوباره تلاش کنید.'); ?></p>
|
||||
</div>
|
||||
<?php elseif ($payment_status === 'error'): ?>
|
||||
<div class="ifnex-error-box">
|
||||
<h3>⚠️ خطا در پرداخت</h3>
|
||||
<p><?php echo esc_html($payment_message ?: 'خطای سیستمی رخ داده است.'); ?></p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
|
||||
<div class="ifnex-order-summary">
|
||||
<div class="ifnex-summary-row">
|
||||
<span>شماره پیگیری:</span>
|
||||
@ -797,7 +829,7 @@ function ifnex_order_payment_shortcode($atts) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php endif; ?>
|
||||
<script>
|
||||
jQuery(document).ready(function($) {
|
||||
// پرداخت از کیف پول
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
if (function_exists('opcache_reset')) { @opcache_reset(); }
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Pragma: no-cache');
|
||||
/**
|
||||
* IFNEX Tracking Form Handler
|
||||
* JavaScript و منطق فرم رهگیری
|
||||
@ -67,6 +70,12 @@ function ifnex_tracking_form_scripts() {
|
||||
};
|
||||
xhr.send('action=ifnex_track_shipment&awb=' + encodeURIComponent(awb));
|
||||
});
|
||||
|
||||
// ارسال خودکار اگر AWB از URL اومده باشد
|
||||
var input = document.getElementById('ifnex-awb-input');
|
||||
if (input && input.value.trim()) {
|
||||
form.dispatchEvent(new Event('submit'));
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
if (function_exists('opcache_reset')) { @opcache_reset(); }
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Pragma: no-cache');
|
||||
/**
|
||||
* IFNEX User Bridge
|
||||
* مدیریت ارتباط کاربران وردپرس با لاراول
|
||||
@ -254,13 +257,24 @@ class IFNEX_User_Bridge {
|
||||
* دریافت لیست کشورها
|
||||
*/
|
||||
public function get_countries($user_id) {
|
||||
$result = $this->authenticated_request($user_id, '/customer/countries');
|
||||
|
||||
if (is_wp_error($result)) {
|
||||
return $result;
|
||||
$api_url = rtrim(get_option('ifnex_api_url', 'http://localhost:8000/api/v1'), '/');
|
||||
$response = wp_remote_get($api_url . '/countries', array(
|
||||
'headers' => array('Accept' => 'application/json'),
|
||||
'timeout' => 15,
|
||||
));
|
||||
|
||||
if (is_wp_error($response)) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
return $result['data'] ?? [];
|
||||
|
||||
$body = json_decode(wp_remote_retrieve_body($response), true);
|
||||
$code = wp_remote_retrieve_response_code($response);
|
||||
|
||||
if ($code !== 200 || empty($body['data'])) {
|
||||
return new WP_Error('countries_error', 'خطا در دریافت لیست کشورها');
|
||||
}
|
||||
|
||||
return $body['data'];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -462,14 +476,14 @@ function ifnex_enqueue_order_assets() {
|
||||
global $post;
|
||||
if (!is_a($post, 'WP_Post')) return;
|
||||
|
||||
$plugin_url = plugin_dir_url(dirname(__FILE__));
|
||||
$plugin_url = trailingslashit(plugins_url('', dirname(__FILE__)));
|
||||
|
||||
// لود CSS
|
||||
// لود CSS — وابسته به CSS قالب
|
||||
wp_enqueue_style(
|
||||
'ifnex-orders-css',
|
||||
$plugin_url . 'assets/css/ifnex-orders.css',
|
||||
array(),
|
||||
'1.7.0'
|
||||
'ifnex-orders-css',
|
||||
$plugin_url . 'assets/css/ifnex-orders.css',
|
||||
array('ifnex-main'),
|
||||
'2.0.0-' . time()
|
||||
);
|
||||
|
||||
// لود jQuery & JS
|
||||
@ -478,7 +492,7 @@ function ifnex_enqueue_order_assets() {
|
||||
'ifnex-order-form-js',
|
||||
$plugin_url . 'assets/js/ifnex-order-form.js',
|
||||
array('jquery'),
|
||||
'1.7.0',
|
||||
'2.0.0-' . time(),
|
||||
true
|
||||
);
|
||||
|
||||
@ -486,7 +500,7 @@ function ifnex_enqueue_order_assets() {
|
||||
wp_localize_script('ifnex-order-form-js', 'ifnex_ajax', array(
|
||||
'ajax_url' => admin_url('admin-ajax.php'),
|
||||
'nonce' => wp_create_nonce('ifnex_ajax_nonce'),
|
||||
'orders_url' => home_url('/my-orders/'),
|
||||
'orders_url' => home_url('/my-account/?tab=orders'),
|
||||
));
|
||||
}
|
||||
|
||||
@ -532,6 +546,41 @@ function ifnex_wallet_charge_ajax() {
|
||||
wp_send_json_success($result);
|
||||
}
|
||||
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
// AJAX Handler برای پرداخت سفارش از کیف پول
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
|
||||
add_action('wp_ajax_ifnex_pay_order_wallet', 'ifnex_pay_order_wallet_ajax');
|
||||
|
||||
function ifnex_pay_order_wallet_ajax() {
|
||||
check_ajax_referer('ifnex_ajax_nonce', 'nonce');
|
||||
if (!is_user_logged_in()) {
|
||||
wp_send_json_error('باید وارد شوید.');
|
||||
}
|
||||
|
||||
$order_id = intval($_POST['order_id'] ?? 0);
|
||||
if (!$order_id) {
|
||||
wp_send_json_error('شناسه سفارش نامعتبر است.');
|
||||
}
|
||||
|
||||
$bridge = new IFNEX_User_Bridge();
|
||||
$result = $bridge->authenticated_request(
|
||||
get_current_user_id(),
|
||||
"/customer/orders/{$order_id}/pay-wallet",
|
||||
'POST'
|
||||
);
|
||||
|
||||
if (is_wp_error($result)) {
|
||||
wp_send_json_error($result->get_error_message());
|
||||
}
|
||||
|
||||
if (isset($result['success']) && !$result['success']) {
|
||||
wp_send_json_error($result['message'] ?? 'خطا در پرداخت از کیف پول');
|
||||
}
|
||||
|
||||
wp_send_json_success($result);
|
||||
}
|
||||
|
||||
add_action('wp_ajax_ifnex_pay_order_gateway', 'ifnex_pay_order_gateway_ajax');
|
||||
function ifnex_pay_order_gateway_ajax() {
|
||||
check_ajax_referer('ifnex_ajax_nonce', 'nonce');
|
||||
@ -566,14 +615,19 @@ function ifnex_enqueue_payment_assets() {
|
||||
if (!is_a($post, 'WP_Post')) return;
|
||||
|
||||
if (has_shortcode($post->post_content, 'ifnex_order_payment')) {
|
||||
$plugin_url = plugin_dir_url(dirname(__FILE__));
|
||||
wp_enqueue_style('ifnex-orders-css', $plugin_url . 'assets/css/ifnex-orders.css', array(), '1.4.0');
|
||||
$plugin_url = trailingslashit(plugins_url('', dirname(__FILE__)));
|
||||
wp_enqueue_style(
|
||||
'ifnex-orders-css',
|
||||
$plugin_url . 'assets/css/ifnex-orders.css',
|
||||
array('ifnex-main'),
|
||||
'2.0.0-' . time()
|
||||
);
|
||||
wp_enqueue_script('jquery');
|
||||
wp_localize_script('jquery', 'ifnex_ajax', array(
|
||||
'ajax_url' => admin_url('admin-ajax.php'),
|
||||
'nonce' => wp_create_nonce('ifnex_ajax_nonce'),
|
||||
'orders_url' => home_url('/my-orders/'),
|
||||
));
|
||||
wp_add_inline_script('jquery', 'var ifnex_ajax = ' . wp_json_encode(array(
|
||||
'ajax_url' => admin_url('admin-ajax.php'),
|
||||
'nonce' => wp_create_nonce('ifnex_ajax_nonce'),
|
||||
'orders_url' => home_url('/my-account/?tab=orders'),
|
||||
)) . ';', 'before');
|
||||
}
|
||||
}
|
||||
|
||||
@ -585,24 +639,24 @@ function ifnex_enqueue_payment_assets() {
|
||||
add_action('wp_enqueue_scripts', 'ifnex_enqueue_global_assets', 20);
|
||||
|
||||
function ifnex_enqueue_global_assets() {
|
||||
$plugin_url = plugin_dir_url(dirname(__FILE__));
|
||||
$plugin_url = trailingslashit(plugins_url('', dirname(__FILE__)));
|
||||
|
||||
// لود CSS اصلی (نسخه را بالا بردیم تا cache مرورگر بشکند)
|
||||
// لود CSS اصلی — وابسته به CSS قالب تا بعد از آن لود شود
|
||||
wp_enqueue_style(
|
||||
'ifnex-orders-css',
|
||||
$plugin_url . 'assets/css/ifnex-orders.css',
|
||||
array(),
|
||||
'1.6.0'
|
||||
array('ifnex-main'),
|
||||
'2.0.0-' . time()
|
||||
);
|
||||
|
||||
// لود jQuery
|
||||
wp_enqueue_script('jquery');
|
||||
|
||||
// متغیرهای AJAX برای همه صفحات
|
||||
wp_localize_script('jquery', 'ifnex_ajax', array(
|
||||
wp_add_inline_script('jquery', 'var ifnex_ajax = ' . wp_json_encode(array(
|
||||
'ajax_url' => admin_url('admin-ajax.php'),
|
||||
'nonce' => wp_create_nonce('ifnex_ajax_nonce'),
|
||||
'orders_url' => home_url('/my-account/?tab=orders'),
|
||||
'home_url' => home_url('/'),
|
||||
));
|
||||
)) . ';', 'before');
|
||||
}
|
||||
@ -97,4 +97,32 @@
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Hero Tracking Form ───
|
||||
const trackingForm = document.querySelector('.tracking-form');
|
||||
if (trackingForm) {
|
||||
const trackingInput = trackingForm.querySelector('.tracking-input');
|
||||
const trackingBtn = trackingForm.querySelector('.tracking-btn');
|
||||
|
||||
function submitTracking() {
|
||||
var awb = trackingInput.value.trim();
|
||||
if (!awb) {
|
||||
trackingInput.focus();
|
||||
return;
|
||||
}
|
||||
var baseUrl = (typeof ifnexConfig !== 'undefined' && ifnexConfig.homeUrl) ? ifnexConfig.homeUrl : '/';
|
||||
window.location.href = baseUrl.replace(/\/$/, '') + '/tracking/?awb=' + encodeURIComponent(awb);
|
||||
}
|
||||
|
||||
if (trackingBtn) {
|
||||
trackingBtn.addEventListener('click', submitTracking);
|
||||
}
|
||||
|
||||
trackingInput.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
submitTracking();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
})();
|
||||
@ -176,6 +176,9 @@ function ifnex_get_logo_html($context = 'header') {
|
||||
$custom_logo = wp_get_attachment_image($logo_id, 'full', false, [
|
||||
'class' => 'logo-image',
|
||||
'alt' => get_bloginfo('name'),
|
||||
'loading' => 'eager',
|
||||
'width' => 200,
|
||||
'height' => 50,
|
||||
]);
|
||||
|
||||
if ($custom_logo) {
|
||||
|
||||
@ -134,11 +134,16 @@ class CustomerCreditResource extends Resource
|
||||
'has_available' => 'باقیمانده',
|
||||
])
|
||||
->query(function ($query, $filter) {
|
||||
match ($filter->getState()) {
|
||||
$state = $filter->getState();
|
||||
if (is_array($state)) {
|
||||
$state = $state['value'] ?? null;
|
||||
}
|
||||
match ($state) {
|
||||
'has_limit' => $query->where('credit_limit', '>', 0),
|
||||
'no_limit' => $query->where('credit_limit', 0),
|
||||
'has_used' => $query->where('credit_used', '>', 0),
|
||||
'has_available' => $query->whereRaw('credit_limit - credit_used > 0'),
|
||||
default => null,
|
||||
};
|
||||
}),
|
||||
])
|
||||
|
||||
@ -128,9 +128,11 @@ class ShipmentChecklistResource extends Resource
|
||||
'pending' => 'در انتظار',
|
||||
])
|
||||
->query(function ($query, $filter) {
|
||||
match ($filter->getState()) {
|
||||
$state = is_array($filter->getState()) ? ($filter->getState()['value'] ?? null) : $filter->getState();
|
||||
match ($state) {
|
||||
'completed' => $query->where('is_completed', true),
|
||||
'pending' => $query->where('is_completed', false),
|
||||
default => null,
|
||||
};
|
||||
}),
|
||||
Tables\Filters\SelectFilter::make('status')
|
||||
|
||||
@ -266,24 +266,24 @@ class CustomerOrderController extends Controller
|
||||
|
||||
ShipmentPackage::create([
|
||||
'shipment_id' => $shipment->id,
|
||||
'package_number' => $index + 1,
|
||||
'package_no' => $index + 1,
|
||||
'weight' => $pkg['weight'],
|
||||
'volumetric_weight' => $volWeight,
|
||||
'chargeable_weight' => $chargeable,
|
||||
'dimensions' => $pkg['dimensions'] ?? null,
|
||||
'description' => $pkg['description'] ?? null,
|
||||
'content_description' => $pkg['description'] ?? null,
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
// حالت قدیمی: یه بسته با وزن کلی سفارش
|
||||
ShipmentPackage::create([
|
||||
'shipment_id' => $shipment->id,
|
||||
'package_number' => 1,
|
||||
'package_no' => 1,
|
||||
'weight' => $validated['weight'],
|
||||
'volumetric_weight' => $validated['volumetric_weight'] ?? 0,
|
||||
'chargeable_weight' => $validated['chargeable_weight'],
|
||||
'dimensions' => $validated['dimensions'] ?? null,
|
||||
'description' => null,
|
||||
'content_description' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@ -213,7 +213,14 @@ class PaymentController extends Controller
|
||||
gatewayReferenceId: $verification['ref_id'] ?? $authority
|
||||
);
|
||||
|
||||
// ─── NEW: اگر تراکنش مربوط به سفارش است، status سفارش را تغییر بده ─
|
||||
// اگر تراکنش مربوط به سفارش است، status سفارش را تغییر بده
|
||||
$metadata = $transaction->metadata ?? [];
|
||||
if (!empty($metadata['is_order_payment']) && !empty($metadata['shipment_id'])) {
|
||||
$shipment = \App\Models\Shipment::find($metadata['shipment_id']);
|
||||
if ($shipment && $shipment->status === \App\Enums\ShipmentStatus::Approved) {
|
||||
$shipment->update(['status' => \App\Enums\ShipmentStatus::Processed]);
|
||||
}
|
||||
}
|
||||
|
||||
Log::info('Payment completed successfully', [
|
||||
'transaction_id' => $transaction->id,
|
||||
|
||||
@ -4,11 +4,10 @@ namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class ShipmentChecklist extends Model
|
||||
{
|
||||
use HasFactory, SoftDeletes;
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'shipment_id',
|
||||
|
||||
@ -9,12 +9,12 @@ class ShipmentPackage extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'shipment_id',
|
||||
'package_number',
|
||||
'package_no',
|
||||
'weight',
|
||||
'volumetric_weight',
|
||||
'chargeable_weight',
|
||||
'dimensions',
|
||||
'description',
|
||||
'content_description',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
|
||||
@ -163,7 +163,7 @@ class OrderPaymentService
|
||||
return DB::transaction(function () use ($transaction) {
|
||||
$shipment = Shipment::find($transaction->transactionable_id);
|
||||
|
||||
if (!$shipment || $shipment->status !== ShipmentStatus::PendingPayment) {
|
||||
if (!$shipment || $shipment->status !== ShipmentStatus::Approved) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\IOFactory;
|
||||
|
||||
$reader = IOFactory::createReader('Xlsx');
|
||||
$spreadsheet = $reader->load(__DIR__ . '/../01_Documents/Sheet ENG invoice.xlsx');
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
|
||||
echo 'Sheet: ' . $sheet->getTitle() . PHP_EOL;
|
||||
echo 'Rows: ' . $sheet->getHighestRow() . PHP_EOL;
|
||||
|
||||
// Use toArray for cleaner output
|
||||
$data = $sheet->toArray(null, true, true, true);
|
||||
|
||||
echo PHP_EOL . '=== CONTENT ===' . PHP_EOL;
|
||||
|
||||
foreach ($data as $rowIndex => $row) {
|
||||
$line = '';
|
||||
foreach ($row as $colIndex => $value) {
|
||||
if ($value !== null && trim((string)$value) !== '') {
|
||||
$line .= $colIndex . '=' . trim((string)$value) . ' | ';
|
||||
}
|
||||
}
|
||||
if ($line) echo 'Row' . $rowIndex . ': ' . $line . PHP_EOL;
|
||||
}
|
||||
@ -29,6 +29,13 @@ Route::middleware([ApiKeyMiddleware::class])->prefix('v1')->group(function () {
|
||||
Route::get('/track/{awb_no}', [TrackController::class, 'show']);
|
||||
});
|
||||
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
// API عمومی (بدون نیاز به احراز هویت)
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
Route::prefix('v1')->group(function () {
|
||||
Route::get('/countries', [CustomerOrderController::class, 'countries']);
|
||||
});
|
||||
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
// Auth API (عمومی - برای دریافت توکن)
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
@ -60,8 +67,8 @@ Route::middleware(['auth:sanctum'])->prefix('v1')->group(function () {
|
||||
// پروفایل و آمار
|
||||
Route::get('/profile', [CustomerOrderController::class, 'profile']);
|
||||
|
||||
// لیست کشورها
|
||||
Route::get('/countries', [CustomerOrderController::class, 'countries']);
|
||||
// لیست کشورها (عمومی - بدون نیاز به احراز هویت)
|
||||
// این endpoint در گروه auth:sanctum نیست
|
||||
|
||||
// سفارشات
|
||||
Route::get('/orders', [CustomerOrderController::class, 'index']);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user