731 lines
80 KiB
PHP
731 lines
80 KiB
PHP
<?php
|
||
$licenseIdentity = LicenseService::getClientIdentity();
|
||
$licenseSourceLabels = [
|
||
'settings' => 'Saved in settings',
|
||
'environment' => 'Environment variable',
|
||
'derived' => 'Derived from app name',
|
||
'default' => 'Built-in fallback',
|
||
];
|
||
|
||
$savedLicenseAppName = trim((string)($data['settings']['license_app_name'] ?? ''));
|
||
$savedLicenseAppSlug = trim((string)($data['settings']['license_app_slug'] ?? ''));
|
||
$licenseAppNameInput = $savedLicenseAppName;
|
||
$licenseAppSlugInput = $savedLicenseAppSlug;
|
||
|
||
$settingsTabs = [
|
||
'company' => ['label' => 'Company', 'label_ar' => 'الشركة', 'icon' => 'bi-building'],
|
||
'system' => ['label' => 'System', 'label_ar' => 'النظام', 'icon' => 'bi-sliders'],
|
||
'branding' => ['label' => 'Branding', 'label_ar' => 'الهوية البصرية', 'icon' => 'bi-palette'],
|
||
'integrations' => ['label' => 'Integrations', 'label_ar' => 'التكاملات', 'icon' => 'bi-plug'],
|
||
];
|
||
|
||
$requestedSettingsTab = strtolower(trim((string)($_GET['tab'] ?? ($_POST['settings_active_tab'] ?? 'company'))));
|
||
$activeSettingsTab = array_key_exists($requestedSettingsTab, $settingsTabs) ? $requestedSettingsTab : 'company';
|
||
$currentTimezone = (string)($data['settings']['timezone'] ?? date_default_timezone_get());
|
||
$timezoneIdentifiers = DateTimeZone::listIdentifiers();
|
||
$smtpConfigured = !empty($data['settings']['smtp_host']) && !empty($data['settings']['smtp_user']);
|
||
$wablasConfigured = !empty($data['settings']['wablas_api_url']) && !empty($data['settings']['wablas_token']) && !empty($data['settings']['wablas_security_key']);
|
||
?>
|
||
<div class="row justify-content-center">
|
||
<div class="col-12 col-xxl-10">
|
||
<div class="card border-0 shadow-sm rounded-4 overflow-hidden">
|
||
<div class="card-header bg-white py-3 border-bottom-0 d-flex flex-column flex-lg-row justify-content-between align-items-lg-center gap-3">
|
||
<div class="d-flex align-items-start gap-3">
|
||
<div class="rounded-circle bg-primary bg-opacity-10 p-3 text-primary">
|
||
<i class="bi bi-building-gear fs-4"></i>
|
||
</div>
|
||
<div>
|
||
<h1 class="h5 m-0 fw-bold text-dark" data-en="Company Profile & Settings" data-ar="ملف الشركة والإعدادات">Company Profile & Settings</h1>
|
||
<p class="text-muted small mb-0" data-en="Manage your business identity, operations, branding, and integrations" data-ar="إدارة هوية شركتك وعملياتها وهويتها البصرية والتكاملات">Manage your business identity, operations, branding, and integrations</p>
|
||
</div>
|
||
</div>
|
||
<div class="d-flex flex-wrap gap-2">
|
||
<a href="<?= htmlspecialchars(page_url('copy_outlet_data')) ?>" class="btn btn-outline-primary btn-sm rounded-pill px-3">
|
||
<i class="bi bi-arrow-repeat me-1"></i>
|
||
<span data-en="Sync Outlets" data-ar="مزامنة الفروع">Sync Outlets</span>
|
||
</a>
|
||
</div>
|
||
</div>
|
||
<div class="card-body p-4">
|
||
<div class="alert alert-light border rounded-4 d-flex flex-column flex-xl-row justify-content-between align-items-xl-center gap-3 mb-4 shadow-sm">
|
||
<div>
|
||
<div class="fw-semibold text-dark mb-1" data-en="One place for business, system, branding, and integration settings" data-ar="مكان واحد لإعدادات الشركة والنظام والهوية البصرية والتكاملات">One place for business, system, branding, and integration settings</div>
|
||
<div class="small text-muted" data-en="Tabs keep the page shorter and preserve the selected section after you save." data-ar="التبويبات تجعل الصفحة أقصر وتحافظ على التبويب المحدد بعد الحفظ.">Tabs keep the page shorter and preserve the selected section after you save.</div>
|
||
</div>
|
||
<div class="d-flex flex-wrap gap-2 small">
|
||
<span class="badge rounded-pill text-bg-light border px-3 py-2">
|
||
<i class="bi bi-envelope me-1"></i>
|
||
<?= $smtpConfigured ? 'SMTP ready' : 'SMTP draft' ?>
|
||
</span>
|
||
<span class="badge rounded-pill text-bg-light border px-3 py-2">
|
||
<i class="bi bi-whatsapp me-1"></i>
|
||
<?= $wablasConfigured ? 'Wablas ready' : 'Wablas draft' ?>
|
||
</span>
|
||
</div>
|
||
</div>
|
||
|
||
<form method="POST" enctype="multipart/form-data">
|
||
<input type="hidden" name="settings_active_tab" id="settings-active-tab" value="<?= htmlspecialchars($activeSettingsTab) ?>">
|
||
|
||
<div class="bg-light rounded-4 p-2 mb-4 shadow-sm">
|
||
<ul class="nav nav-pills nav-fill flex-column flex-lg-row gap-2" id="settingsTabs" role="tablist">
|
||
<?php foreach ($settingsTabs as $tabKey => $tabMeta): ?>
|
||
<li class="nav-item flex-fill" role="presentation">
|
||
<button
|
||
class="nav-link rounded-3 text-start text-lg-center px-3 py-3 <?= $activeSettingsTab === $tabKey ? 'active shadow-sm' : 'text-dark' ?>"
|
||
id="settings-tab-<?= htmlspecialchars($tabKey) ?>"
|
||
data-bs-toggle="tab"
|
||
data-bs-target="#settings-pane-<?= htmlspecialchars($tabKey) ?>"
|
||
type="button"
|
||
role="tab"
|
||
aria-controls="settings-pane-<?= htmlspecialchars($tabKey) ?>"
|
||
aria-selected="<?= $activeSettingsTab === $tabKey ? 'true' : 'false' ?>"
|
||
data-tab-key="<?= htmlspecialchars($tabKey) ?>"
|
||
>
|
||
<span class="d-inline-flex align-items-center gap-2 fw-semibold">
|
||
<i class="bi <?= htmlspecialchars($tabMeta['icon']) ?>"></i>
|
||
<span data-en="<?= htmlspecialchars($tabMeta['label']) ?>" data-ar="<?= htmlspecialchars($tabMeta['label_ar']) ?>"><?= $lang === 'ar' ? $tabMeta['label_ar'] : $tabMeta['label'] ?></span>
|
||
</span>
|
||
</button>
|
||
</li>
|
||
<?php endforeach; ?>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="tab-content" id="settingsTabsContent">
|
||
<div class="tab-pane fade <?= $activeSettingsTab === 'company' ? 'show active' : '' ?>" id="settings-pane-company" role="tabpanel" aria-labelledby="settings-tab-company">
|
||
<div class="row g-4">
|
||
<div class="col-12 col-xl-6">
|
||
<div class="card border-0 shadow-sm h-100 rounded-4">
|
||
<div class="card-body p-4">
|
||
<div class="d-flex align-items-center gap-2 mb-3">
|
||
<div class="rounded-circle bg-primary bg-opacity-10 text-primary p-2"><i class="bi bi-building"></i></div>
|
||
<div>
|
||
<h2 class="h6 fw-bold mb-0" data-en="Company Details" data-ar="تفاصيل الشركة">Company Details</h2>
|
||
<p class="text-muted small mb-0" data-en="Legal and tax identity used across documents" data-ar="الهوية القانونية والضريبية المستخدمة في المستندات">Legal and tax identity used across documents</p>
|
||
</div>
|
||
</div>
|
||
<div class="row g-3">
|
||
<div class="col-md-12">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Company Name" data-ar="اسم الشركة">Company Name</label>
|
||
<div class="input-group">
|
||
<span class="input-group-text bg-light border-end-0"><i class="bi bi-building"></i></span>
|
||
<input type="text" name="settings[company_name]" class="form-control border-start-0 ps-0" value="<?= htmlspecialchars($data['settings']['company_name'] ?? '') ?>" placeholder="e.g. Tech Solutions LLC">
|
||
</div>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label class="form-label text-muted small fw-semibold" data-en="CTR No (Commercial Registration)" data-ar="رقم السجل التجاري">CTR No (Commercial Registration)</label>
|
||
<div class="input-group">
|
||
<span class="input-group-text bg-light border-end-0"><i class="bi bi-file-text"></i></span>
|
||
<input type="text" name="settings[ctr_no]" class="form-control border-start-0 ps-0" value="<?= htmlspecialchars($data['settings']['ctr_no'] ?? '') ?>" placeholder="e.g. 1234567">
|
||
</div>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label class="form-label text-muted small fw-semibold" data-en="VAT Number" data-ar="الرقم الضريبي">VAT Number</label>
|
||
<div class="input-group">
|
||
<span class="input-group-text bg-light border-end-0"><i class="bi bi-receipt"></i></span>
|
||
<input type="text" name="settings[vat_number]" class="form-control border-start-0 ps-0" value="<?= htmlspecialchars($data['settings']['vat_number'] ?? '') ?>" placeholder="e.g. OM123456789">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-12 col-xl-6">
|
||
<div class="card border-0 shadow-sm h-100 rounded-4">
|
||
<div class="card-body p-4">
|
||
<div class="d-flex align-items-center gap-2 mb-3">
|
||
<div class="rounded-circle bg-primary bg-opacity-10 text-primary p-2"><i class="bi bi-telephone"></i></div>
|
||
<div>
|
||
<h2 class="h6 fw-bold mb-0" data-en="Contact Information" data-ar="معلومات الاتصال">Contact Information</h2>
|
||
<p class="text-muted small mb-0" data-en="Shown in invoices, receipts, and customer-facing documents" data-ar="تظهر في الفواتير والإيصالات والمستندات الموجهة للعملاء">Shown in invoices, receipts, and customer-facing documents</p>
|
||
</div>
|
||
</div>
|
||
<div class="row g-3">
|
||
<div class="col-md-6">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Phone Number" data-ar="رقم الهاتف">Phone Number</label>
|
||
<div class="input-group">
|
||
<span class="input-group-text bg-light border-end-0"><i class="bi bi-phone"></i></span>
|
||
<input type="text" name="settings[company_phone]" class="form-control border-start-0 ps-0" value="<?= htmlspecialchars($data['settings']['company_phone'] ?? '') ?>" placeholder="+968 9999 9999">
|
||
</div>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Email Address" data-ar="البريد الإلكتروني">Email Address</label>
|
||
<div class="input-group">
|
||
<span class="input-group-text bg-light border-end-0"><i class="bi bi-envelope"></i></span>
|
||
<input type="email" name="settings[company_email]" class="form-control border-start-0 ps-0" value="<?= htmlspecialchars($data['settings']['company_email'] ?? '') ?>" placeholder="info@example.com">
|
||
</div>
|
||
</div>
|
||
<div class="col-12">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Physical Address" data-ar="العنوان الفعلي">Physical Address</label>
|
||
<div class="input-group">
|
||
<span class="input-group-text bg-light border-end-0"><i class="bi bi-geo-alt"></i></span>
|
||
<textarea name="settings[company_address]" class="form-control border-start-0 ps-0" rows="5" placeholder="Street, Building, City..."><?= htmlspecialchars($data['settings']['company_address'] ?? '') ?></textarea>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="tab-pane fade <?= $activeSettingsTab === 'system' ? 'show active' : '' ?>" id="settings-pane-system" role="tabpanel" aria-labelledby="settings-tab-system">
|
||
<div class="row g-4">
|
||
<div class="col-12 col-xl-6">
|
||
<div class="card border-0 shadow-sm h-100 rounded-4">
|
||
<div class="card-body p-4">
|
||
<div class="d-flex align-items-center gap-2 mb-3">
|
||
<div class="rounded-circle bg-primary bg-opacity-10 text-primary p-2"><i class="bi bi-sliders"></i></div>
|
||
<div>
|
||
<h2 class="h6 fw-bold mb-0" data-en="System Configuration" data-ar="تكوين النظام">System Configuration</h2>
|
||
<p class="text-muted small mb-0" data-en="Operational rules that affect inventory and barcode behavior" data-ar="قواعد التشغيل التي تؤثر على المخزون وسلوك الباركود">Operational rules that affect inventory and barcode behavior</p>
|
||
</div>
|
||
</div>
|
||
<div class="row g-3">
|
||
<div class="col-md-12">
|
||
<label class="form-label text-muted small fw-semibold" data-en="System Timezone" data-ar="المنطقة الزمنية للنظام">System Timezone</label>
|
||
<select name="settings[timezone]" class="form-select">
|
||
<?php foreach ($timezoneIdentifiers as $tz): ?>
|
||
<option value="<?= htmlspecialchars($tz) ?>" <?= $tz === $currentTimezone ? 'selected' : '' ?>><?= htmlspecialchars($tz) ?></option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
</div>
|
||
<div class="col-md-12">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Stock Policy" data-ar="سياسة المخزون">Stock Policy</label>
|
||
<select name="settings[allow_zero_stock_sell]" class="form-select">
|
||
<option value="0" <?= ($data['settings']['allow_zero_stock_sell'] ?? '1') === '0' ? 'selected' : '' ?> data-en="Prevent selling out of stock" data-ar="منع البيع عند نفاذ المخزون">Prevent selling out of stock</option>
|
||
<option value="1" <?= ($data['settings']['allow_zero_stock_sell'] ?? '1') === '1' ? 'selected' : '' ?> data-en="Allow selling out of stock" data-ar="السماح بالبيع عند نفاذ المخزون">Allow selling out of stock</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-md-12">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Manual Discount in Sales & POS" data-ar="الخصم اليدوي في المبيعات ونقاط البيع">Manual Discount in Sales & POS</label>
|
||
<select name="settings[manual_discount_enabled]" class="form-select">
|
||
<option value="0" <?= ($data['settings']['manual_discount_enabled'] ?? '0') === '1' ? '' : 'selected' ?> data-en="Disabled" data-ar="معطل">Disabled</option>
|
||
<option value="1" <?= ($data['settings']['manual_discount_enabled'] ?? '0') === '1' ? 'selected' : '' ?> data-en="Enabled" data-ar="مفعل">Enabled</option>
|
||
</select>
|
||
<div class="form-text" data-en="Shows a fixed discount amount field on POS and Sales invoices." data-ar="يعرض حقل خصم ثابت في نقاط البيع وفواتير المبيعات.">Shows a fixed discount amount field on POS and Sales invoices.</div>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Scale Barcode Mode" data-ar="وضع باركود الميزان">Scale Barcode Mode</label>
|
||
<select name="settings[weight_barcode_mode]" class="form-select">
|
||
<option value="weight" <?= ($data['settings']['weight_barcode_mode'] ?? 'weight') === 'weight' ? 'selected' : '' ?> data-en="Use embedded weight" data-ar="استخدام الوزن">Use embedded weight</option>
|
||
<option value="price" <?= ($data['settings']['weight_barcode_mode'] ?? '') === 'price' ? 'selected' : '' ?> data-en="Use embedded price" data-ar="استخدام السعر">Use embedded price</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Scale Prefix From" data-ar="بادئة الميزان من">Scale Prefix From</label>
|
||
<input type="number" min="20" max="29" name="settings[weight_barcode_prefix_start]" class="form-control" value="<?= htmlspecialchars($data['settings']['weight_barcode_prefix_start'] ?? '20') ?>">
|
||
</div>
|
||
<div class="col-md-4">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Scale Prefix To" data-ar="بادئة الميزان إلى">Scale Prefix To</label>
|
||
<input type="number" min="20" max="29" name="settings[weight_barcode_prefix_end]" class="form-control" value="<?= htmlspecialchars($data['settings']['weight_barcode_prefix_end'] ?? '29') ?>">
|
||
</div>
|
||
<div class="col-12">
|
||
<div class="form-text" data-en="13-digit scale barcode format: 2-digit prefix + 5-digit item code + 5-digit value + 1 check digit. Full 13-digit scale barcodes are reserved and cannot be saved on items or imported." data-ar="صيغة باركود الميزان 13 رقمًا: بادئة من رقمين + كود صنف من 5 أرقام + قيمة من 5 أرقام + رقم تحقق. الباركود الكامل 13 رقمًا محجوز ولا يمكن حفظه أو استيراده كصنف.">13-digit scale barcode format: 2-digit prefix + 5-digit item code + 5-digit value + 1 check digit. Full 13-digit scale barcodes are reserved and cannot be saved on items or imported.</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-12 col-xl-6">
|
||
<div class="card border-0 shadow-sm h-100 rounded-4">
|
||
<div class="card-body p-4">
|
||
<div class="d-flex justify-content-between align-items-start flex-wrap gap-3 mb-3">
|
||
<div>
|
||
<h2 class="h6 fw-bold mb-1" data-en="License App Identity" data-ar="هوية ترخيص التطبيق">License App Identity</h2>
|
||
<p class="text-muted small mb-0" data-en="Stable product identity used by the central license manager" data-ar="هوية منتج ثابتة يستخدمها مدير التراخيص المركزي">Stable product identity used by the central license manager</p>
|
||
</div>
|
||
<span class="badge rounded-pill text-bg-light border">
|
||
<span data-en="Name source" data-ar="مصدر الاسم">Name source</span>: <?= htmlspecialchars($licenseSourceLabels[$licenseIdentity['app_name_source']] ?? 'Built-in fallback') ?>
|
||
·
|
||
<span data-en="Slug source" data-ar="مصدر المعرّف">Slug source</span>: <?= htmlspecialchars($licenseSourceLabels[$licenseIdentity['app_slug_source']] ?? 'Built-in fallback') ?>
|
||
</span>
|
||
</div>
|
||
<div class="alert alert-info border-0 shadow-sm small mb-3">
|
||
<strong data-en="Use one stable identity per product." data-ar="استخدم هوية ثابتة لكل منتج.">Use one stable identity per product.</strong>
|
||
<span data-en="Change the slug only when you intentionally rename or split a product." data-ar="غيّر المعرّف فقط عندما تقصد إعادة تسمية المنتج أو تقسيمه.">Change the slug only when you intentionally rename or split a product.</span>
|
||
</div>
|
||
<div class="row g-3">
|
||
<div class="col-md-12">
|
||
<label class="form-label text-muted small fw-semibold" data-en="App Name for Licensing" data-ar="اسم التطبيق للترخيص">App Name for Licensing</label>
|
||
<div class="input-group">
|
||
<span class="input-group-text bg-light border-end-0"><i class="bi bi-window"></i></span>
|
||
<input type="text" id="license-app-name" name="settings[license_app_name]" class="form-control border-start-0 ps-0" value="<?= htmlspecialchars($licenseAppNameInput) ?>" placeholder="<?= htmlspecialchars((string)$licenseIdentity['app_name']) ?>">
|
||
</div>
|
||
<div class="form-text" data-en="Leave blank only if you want to fall back to environment/default values." data-ar="اتركه فارغًا فقط إذا كنت تريد الرجوع إلى قيم البيئة أو القيم الافتراضية.">Leave blank only if you want to fall back to environment/default values.</div>
|
||
</div>
|
||
<div class="col-md-12">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Stable App Slug" data-ar="المعرّف الثابت للتطبيق">Stable App Slug</label>
|
||
<div class="input-group">
|
||
<span class="input-group-text bg-light border-end-0"><i class="bi bi-tag"></i></span>
|
||
<input type="text" id="license-app-slug" name="settings[license_app_slug]" data-explicit="<?= $savedLicenseAppSlug !== '' ? '1' : '0' ?>" class="form-control border-start-0 ps-0" value="<?= htmlspecialchars($licenseAppSlugInput) ?>" placeholder="<?= htmlspecialchars((string)$licenseIdentity['app_slug']) ?>">
|
||
<button type="button" class="btn btn-outline-secondary" id="suggest-license-slug" data-en="Suggest" data-ar="اقتراح">Suggest</button>
|
||
</div>
|
||
<div class="form-text" data-en="Use one slug per product, not per customer or installation." data-ar="استخدم معرّفًا واحدًا لكل منتج، وليس لكل عميل أو تثبيت.">Use one slug per product, not per customer or installation.</div>
|
||
</div>
|
||
<div class="col-12">
|
||
<div class="form-text">
|
||
<span data-en="Current effective identity:" data-ar="هوية التطبيق الفعالة حاليًا:">Current effective identity:</span>
|
||
<code><?= htmlspecialchars((string)$licenseIdentity['app_name']) ?></code>
|
||
·
|
||
<code><?= htmlspecialchars((string)$licenseIdentity['app_slug']) ?></code>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-12">
|
||
<div class="card border-0 shadow-sm rounded-4">
|
||
<div class="card-body p-4">
|
||
<div class="d-flex align-items-center gap-2 mb-3">
|
||
<div class="rounded-circle bg-primary bg-opacity-10 text-primary p-2"><i class="bi bi-award"></i></div>
|
||
<div>
|
||
<h2 class="h6 fw-bold mb-0" data-en="Loyalty Program" data-ar="برنامج الولاء">Loyalty Program</h2>
|
||
<p class="text-muted small mb-0" data-en="Control how customers earn and redeem loyalty points" data-ar="التحكم في كيفية كسب العملاء لنقاط الولاء واستردادها">Control how customers earn and redeem loyalty points</p>
|
||
</div>
|
||
</div>
|
||
<div class="row g-3">
|
||
<div class="col-md-4">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Loyalty Status" data-ar="حالة الولاء">Loyalty Status</label>
|
||
<select name="settings[loyalty_enabled]" class="form-select">
|
||
<option value="0" <?= ($data['settings']['loyalty_enabled'] ?? '0') === '0' ? 'selected' : '' ?> data-en="Disabled" data-ar="معطل">Disabled</option>
|
||
<option value="1" <?= ($data['settings']['loyalty_enabled'] ?? '0') === '1' ? 'selected' : '' ?> data-en="Active" data-ar="نشط">Active</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Earning Rule (Points/1 OMR)" data-ar="قاعدة الكسب (نقاط/1 ريال)">Earning Rule (Points/1 OMR)</label>
|
||
<div class="input-group">
|
||
<span class="input-group-text bg-light border-end-0"><i class="bi bi-arrow-up-circle"></i></span>
|
||
<input type="number" step="0.01" name="settings[loyalty_points_per_unit]" class="form-control border-start-0 ps-0" value="<?= htmlspecialchars($data['settings']['loyalty_points_per_unit'] ?? '1') ?>">
|
||
</div>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Redemption Rule (Points/1 OMR)" data-ar="قاعدة الاسترداد (نقاط/1 ريال)">Redemption Rule (Points/1 OMR)</label>
|
||
<div class="input-group">
|
||
<span class="input-group-text bg-light border-end-0"><i class="bi bi-arrow-down-circle"></i></span>
|
||
<input type="number" step="0.01" name="settings[loyalty_redeem_points_per_unit]" class="form-control border-start-0 ps-0" value="<?= htmlspecialchars($data['settings']['loyalty_redeem_points_per_unit'] ?? '100') ?>">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="tab-pane fade <?= $activeSettingsTab === 'branding' ? 'show active' : '' ?>" id="settings-pane-branding" role="tabpanel" aria-labelledby="settings-tab-branding">
|
||
<div class="card border-0 shadow-sm rounded-4">
|
||
<div class="card-body p-4">
|
||
<div class="d-flex align-items-center gap-2 mb-3">
|
||
<div class="rounded-circle bg-primary bg-opacity-10 text-primary p-2"><i class="bi bi-palette"></i></div>
|
||
<div>
|
||
<h2 class="h6 fw-bold mb-0" data-en="Visual Identity" data-ar="الهوية البصرية">Visual Identity</h2>
|
||
<p class="text-muted small mb-0" data-en="Upload the brand assets used across receipts, browser tabs, and approvals" data-ar="قم برفع الأصول البصرية المستخدمة في الإيصالات وعلامات المتصفح والاعتمادات">Upload the brand assets used across receipts, browser tabs, and approvals</p>
|
||
</div>
|
||
</div>
|
||
<div class="row g-4">
|
||
<div class="col-md-4">
|
||
<div class="card h-100 border rounded-4 bg-light text-center p-3">
|
||
<label class="form-label fw-semibold mb-2" data-en="Company Logo" data-ar="شعار الشركة">Company Logo</label>
|
||
<div class="mb-3 d-flex justify-content-center align-items-center" style="height: 110px;">
|
||
<?php if (!empty($data['settings']['company_logo'])): ?>
|
||
<img src="<?= htmlspecialchars($data['settings']['company_logo']) ?>?v=<?= time() ?>" alt="Company logo" class="img-fluid" style="max-height: 90px;">
|
||
<?php else: ?>
|
||
<i class="bi bi-image text-muted fs-1"></i>
|
||
<?php endif; ?>
|
||
</div>
|
||
<input type="file" name="company_logo" class="form-control form-control-sm" accept="image/*">
|
||
<div class="form-text mt-2">PNG or SVG recommended.</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<div class="card h-100 border rounded-4 bg-light text-center p-3">
|
||
<label class="form-label fw-semibold mb-2" data-en="Website Favicon" data-ar="أيقونة الموقع">Website Favicon</label>
|
||
<div class="mb-3 d-flex justify-content-center align-items-center" style="height: 110px;">
|
||
<?php if (!empty($data['settings']['favicon'])): ?>
|
||
<img src="<?= htmlspecialchars($data['settings']['favicon']) ?>?v=<?= time() ?>" alt="Favicon" class="img-fluid" style="max-height: 36px;">
|
||
<?php else: ?>
|
||
<i class="bi bi-globe text-muted fs-1"></i>
|
||
<?php endif; ?>
|
||
</div>
|
||
<input type="file" name="favicon" class="form-control form-control-sm" accept="image/*,.ico">
|
||
<div class="form-text mt-2">Square icon works best.</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<div class="card h-100 border rounded-4 bg-light text-center p-3">
|
||
<label class="form-label fw-semibold mb-2" data-en="Manager Signature" data-ar="توقيع المدير">Manager Signature</label>
|
||
<div class="mb-3 d-flex justify-content-center align-items-center" style="height: 110px;">
|
||
<?php if (!empty($data['settings']['manager_signature'])): ?>
|
||
<img src="<?= htmlspecialchars($data['settings']['manager_signature']) ?>?v=<?= time() ?>" alt="Manager signature" class="img-fluid" style="max-height: 90px;">
|
||
<?php else: ?>
|
||
<i class="bi bi-pen text-muted fs-1"></i>
|
||
<?php endif; ?>
|
||
</div>
|
||
<input type="file" name="manager_signature" class="form-control form-control-sm" accept="image/*">
|
||
<div class="form-text mt-2">Used on approvals and printouts.</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="tab-pane fade <?= $activeSettingsTab === 'integrations' ? 'show active' : '' ?>" id="settings-pane-integrations" role="tabpanel" aria-labelledby="settings-tab-integrations">
|
||
<div class="row g-4">
|
||
<div class="col-12">
|
||
<div class="alert alert-warning border-0 shadow-sm rounded-4 mb-0">
|
||
<div class="fw-semibold mb-1" data-en="Integration profiles are now grouped here" data-ar="تم تجميع ملفات التكامل هنا">Integration profiles are now grouped here</div>
|
||
<div class="small mb-0" data-en="SMTP settings are saved from the admin UI for integration workflows, while the built-in MailService still remains the app’s email engine. Wablas connection, security key, recipients, templates, and schedule fields are now grouped here for WhatsApp automation flows." data-ar="يتم حفظ إعدادات SMTP من واجهة الإدارة لسير عمل التكامل، بينما يظل MailService المدمج هو محرك البريد في التطبيق. كما تم تجميع اتصال Wablas ومفتاح الأمان والمستلمين والقوالب وحقول الجدولة هنا لتدفقات أتمتة واتساب.">SMTP settings are saved from the admin UI for integration workflows, while the built-in MailService still remains the app’s email engine. Wablas connection, security key, recipients, templates, and schedule fields are now grouped here for WhatsApp automation flows.</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="col-12 col-xl-6">
|
||
<div class="card border-0 shadow-sm h-100 rounded-4">
|
||
<div class="card-body p-4">
|
||
<div class="d-flex align-items-center justify-content-between flex-wrap gap-2 mb-3">
|
||
<div class="d-flex align-items-center gap-2">
|
||
<div class="rounded-circle bg-primary bg-opacity-10 text-primary p-2"><i class="bi bi-envelope"></i></div>
|
||
<div>
|
||
<h2 class="h6 fw-bold mb-0" data-en="SMTP Email" data-ar="بريد SMTP">SMTP Email</h2>
|
||
<p class="text-muted small mb-0" data-en="Store the outgoing email profile used by your business" data-ar="احفظ ملف البريد الصادر المستخدم في عملك">Store the outgoing email profile used by your business</p>
|
||
</div>
|
||
</div>
|
||
<span class="badge rounded-pill <?= ($data['settings']['smtp_enabled'] ?? '0') === '1' ? 'bg-success bg-opacity-10 text-success' : 'text-bg-light border' ?> px-3 py-2">
|
||
<?= ($data['settings']['smtp_enabled'] ?? '0') === '1' ? 'Enabled' : 'Disabled' ?>
|
||
</span>
|
||
</div>
|
||
<div class="row g-3">
|
||
<div class="col-md-4">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Status" data-ar="الحالة">Status</label>
|
||
<select name="settings[smtp_enabled]" class="form-select">
|
||
<option value="0" <?= ($data['settings']['smtp_enabled'] ?? '0') === '0' ? 'selected' : '' ?>>Disabled</option>
|
||
<option value="1" <?= ($data['settings']['smtp_enabled'] ?? '0') === '1' ? 'selected' : '' ?>>Enabled</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-md-8">
|
||
<label class="form-label text-muted small fw-semibold" data-en="SMTP Host" data-ar="خادم SMTP">SMTP Host</label>
|
||
<input type="text" name="settings[smtp_host]" class="form-control" value="<?= htmlspecialchars($data['settings']['smtp_host'] ?? '') ?>" placeholder="smtp.office365.com">
|
||
</div>
|
||
<div class="col-md-4">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Port" data-ar="المنفذ">Port</label>
|
||
<input type="number" min="1" max="65535" name="settings[smtp_port]" class="form-control" value="<?= htmlspecialchars($data['settings']['smtp_port'] ?? '') ?>" placeholder="587">
|
||
</div>
|
||
<div class="col-md-4">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Security" data-ar="التشفير">Security</label>
|
||
<select name="settings[smtp_secure]" class="form-select">
|
||
<?php $smtpSecure = $data['settings']['smtp_secure'] ?? 'tls'; ?>
|
||
<option value="tls" <?= $smtpSecure === 'tls' ? 'selected' : '' ?>>TLS</option>
|
||
<option value="ssl" <?= $smtpSecure === 'ssl' ? 'selected' : '' ?>>SSL</option>
|
||
<option value="none" <?= $smtpSecure === 'none' ? 'selected' : '' ?>>None</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Username" data-ar="اسم المستخدم">Username</label>
|
||
<input type="text" name="settings[smtp_user]" class="form-control" value="<?= htmlspecialchars($data['settings']['smtp_user'] ?? '') ?>" placeholder="mailer@example.com">
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Password" data-ar="كلمة المرور">Password</label>
|
||
<input type="password" name="settings[smtp_pass]" class="form-control" value="<?= htmlspecialchars($data['settings']['smtp_pass'] ?? '') ?>" autocomplete="new-password" placeholder="SMTP password">
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label class="form-label text-muted small fw-semibold" data-en="From Email" data-ar="بريد الإرسال">From Email</label>
|
||
<input type="email" name="settings[smtp_from_email]" class="form-control" value="<?= htmlspecialchars($data['settings']['smtp_from_email'] ?? '') ?>" placeholder="no-reply@example.com">
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label class="form-label text-muted small fw-semibold" data-en="From Name" data-ar="اسم المرسل">From Name</label>
|
||
<input type="text" name="settings[smtp_from_name]" class="form-control" value="<?= htmlspecialchars($data['settings']['smtp_from_name'] ?? '') ?>" placeholder="Your Company">
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Reply-To Email" data-ar="الرد إلى">Reply-To Email</label>
|
||
<input type="email" name="settings[smtp_reply_to]" class="form-control" value="<?= htmlspecialchars($data['settings']['smtp_reply_to'] ?? '') ?>" placeholder="support@example.com">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="col-12 col-xl-6">
|
||
<div class="card border-0 shadow-sm h-100 rounded-4">
|
||
<div class="card-body p-4">
|
||
<div class="d-flex align-items-center justify-content-between flex-wrap gap-2 mb-3">
|
||
<div class="d-flex align-items-center gap-2">
|
||
<div class="rounded-circle bg-success bg-opacity-10 text-success p-2"><i class="bi bi-whatsapp"></i></div>
|
||
<div>
|
||
<h2 class="h6 fw-bold mb-0" data-en="Wablas WhatsApp Gateway" data-ar="بوابة واتساب Wablas">Wablas WhatsApp Gateway</h2>
|
||
<p class="text-muted small mb-0" data-en="Keep the WhatsApp channel profile ready for alerts and automations" data-ar="جهّز ملف قناة واتساب للتنبيهات والأتمتة">Keep the WhatsApp channel profile ready for alerts and automations</p>
|
||
</div>
|
||
</div>
|
||
<span class="badge rounded-pill <?= ($data['settings']['wablas_enabled'] ?? '0') === '1' ? 'bg-success bg-opacity-10 text-success' : 'text-bg-light border' ?> px-3 py-2">
|
||
<?= ($data['settings']['wablas_enabled'] ?? '0') === '1' ? 'Enabled' : 'Disabled' ?>
|
||
</span>
|
||
</div>
|
||
<div class="row g-3">
|
||
<div class="col-md-4">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Status" data-ar="الحالة">Status</label>
|
||
<select name="settings[wablas_enabled]" class="form-select">
|
||
<option value="0" <?= ($data['settings']['wablas_enabled'] ?? '0') === '0' ? 'selected' : '' ?>>Disabled</option>
|
||
<option value="1" <?= ($data['settings']['wablas_enabled'] ?? '0') === '1' ? 'selected' : '' ?>>Enabled</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-md-8">
|
||
<label class="form-label text-muted small fw-semibold" data-en="API URL" data-ar="رابط API">API URL</label>
|
||
<input type="url" name="settings[wablas_api_url]" class="form-control" value="<?= htmlspecialchars($data['settings']['wablas_api_url'] ?? '') ?>" placeholder="https://your-wablas-endpoint">
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label class="form-label text-muted small fw-semibold" data-en="API Token" data-ar="رمز API">API Token</label>
|
||
<input type="password" name="settings[wablas_token]" class="form-control" value="<?= htmlspecialchars($data['settings']['wablas_token'] ?? '') ?>" autocomplete="new-password" placeholder="Wablas access token">
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Security Key" data-ar="مفتاح الأمان">Security Key</label>
|
||
<input type="password" name="settings[wablas_security_key]" class="form-control" value="<?= htmlspecialchars($data['settings']['wablas_security_key'] ?? '') ?>" autocomplete="new-password" placeholder="Wablas security key">
|
||
</div>
|
||
<div class="col-md-7">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Sender / Device / Phone" data-ar="المرسل / الجهاز / الهاتف">Sender / Device / Phone</label>
|
||
<input type="text" name="settings[wablas_sender]" class="form-control" value="<?= htmlspecialchars($data['settings']['wablas_sender'] ?? '') ?>" placeholder="Instance, device, or WhatsApp number">
|
||
</div>
|
||
<div class="col-md-5">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Default Country Code" data-ar="رمز الدولة الافتراضي">Default Country Code</label>
|
||
<input type="text" name="settings[wablas_default_country_code]" class="form-control" value="<?= htmlspecialchars($data['settings']['wablas_default_country_code'] ?? '') ?>" placeholder="+968">
|
||
</div>
|
||
<div class="col-12">
|
||
<div class="form-text" data-en="Use the API URL, token, and security key from your Wablas dashboard. This profile will be ready for WhatsApp notifications and future automation hooks." data-ar="استخدم رابط API والرمز ومفتاح الأمان من لوحة تحكم Wablas. سيكون هذا الملف جاهزًا لإشعارات واتساب وخطافات الأتمتة المستقبلية.">Use the API URL, token, and security key from your Wablas dashboard. This profile will be ready for WhatsApp notifications and future automation hooks.</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="col-12">
|
||
<div class="card border-0 shadow-sm rounded-4">
|
||
<div class="card-body p-4">
|
||
<div class="d-flex align-items-center justify-content-between flex-wrap gap-2 mb-4">
|
||
<div class="d-flex align-items-center gap-2">
|
||
<div class="rounded-circle bg-dark bg-opacity-10 text-dark p-2"><i class="bi bi-chat-dots"></i></div>
|
||
<div>
|
||
<h2 class="h6 fw-bold mb-0" data-en="WhatsApp Templates & Schedule" data-ar="قوالب واتساب والجدولة">WhatsApp Templates & Schedule</h2>
|
||
<p class="text-muted small mb-0" data-en="Prepare invoice and daily summary messages with fixed recipients and a saved send time" data-ar="جهّز رسائل الفاتورة والملخص اليومي مع مستلمين ثابتين ووقت إرسال محفوظ">Prepare invoice and daily summary messages with fixed recipients and a saved send time</p>
|
||
</div>
|
||
</div>
|
||
<span class="badge rounded-pill text-bg-light border px-3 py-2">Ready for automation</span>
|
||
</div>
|
||
|
||
<div class="row g-4">
|
||
<div class="col-12 col-xl-6">
|
||
<div class="border rounded-4 p-4 h-100 bg-light bg-opacity-50">
|
||
<div class="d-flex align-items-start justify-content-between gap-2 mb-3">
|
||
<div>
|
||
<h3 class="h6 fw-bold mb-1" data-en="Invoice Message" data-ar="رسالة الفاتورة">Invoice Message</h3>
|
||
<p class="text-muted small mb-0" data-en="Choose who receives invoice WhatsApp messages and keep a reusable template" data-ar="اختر من يستلم رسائل الفاتورة عبر واتساب واحتفظ بقالب قابل لإعادة الاستخدام">Choose who receives invoice WhatsApp messages and keep a reusable template</p>
|
||
</div>
|
||
<span class="badge rounded-pill <?= ($data['settings']['wablas_invoice_enabled'] ?? '0') === '1' ? 'bg-success bg-opacity-10 text-success' : 'text-bg-light border' ?> px-3 py-2">
|
||
<?= ($data['settings']['wablas_invoice_enabled'] ?? '0') === '1' ? 'Enabled' : 'Disabled' ?>
|
||
</span>
|
||
</div>
|
||
<div class="row g-3">
|
||
<div class="col-md-4">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Status" data-ar="الحالة">Status</label>
|
||
<select name="settings[wablas_invoice_enabled]" class="form-select">
|
||
<option value="0" <?= ($data['settings']['wablas_invoice_enabled'] ?? '0') === '0' ? 'selected' : '' ?>>Disabled</option>
|
||
<option value="1" <?= ($data['settings']['wablas_invoice_enabled'] ?? '0') === '1' ? 'selected' : '' ?>>Enabled</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-md-8">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Preferred Send Time" data-ar="وقت الإرسال المفضل">Preferred Send Time</label>
|
||
<input type="time" name="settings[wablas_invoice_time]" class="form-control" value="<?= htmlspecialchars($data['settings']['wablas_invoice_time'] ?? '') ?>">
|
||
<div class="form-text" data-en="Optional. Leave blank if invoices should go out immediately when the invoice workflow is triggered." data-ar="اختياري. اتركه فارغًا إذا كان يجب إرسال الفواتير فور تشغيل سير عمل الفاتورة.">Optional. Leave blank if invoices should go out immediately when the invoice workflow is triggered.</div>
|
||
</div>
|
||
<div class="col-12">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Recipient Numbers" data-ar="أرقام المستلمين">Recipient Numbers</label>
|
||
<textarea name="settings[wablas_invoice_numbers]" class="form-control" rows="3" placeholder="+96890000000 +96891111111"><?= htmlspecialchars($data['settings']['wablas_invoice_numbers'] ?? '') ?></textarea>
|
||
<div class="form-text" data-en="Use one number per line or separate numbers with commas. Include the country code." data-ar="استخدم رقمًا واحدًا في كل سطر أو افصل الأرقام بفواصل. ضمّن رمز الدولة.">Use one number per line or separate numbers with commas. Include the country code.</div>
|
||
</div>
|
||
<div class="col-12">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Invoice Template" data-ar="قالب الفاتورة">Invoice Template</label>
|
||
<textarea name="settings[wablas_invoice_template]" class="form-control" rows="6" placeholder="Hello {customer_name}, your invoice {invoice_no} total is {grand_total}. View: {invoice_url}"><?= htmlspecialchars($data['settings']['wablas_invoice_template'] ?? '') ?></textarea>
|
||
<div class="form-text" data-en="Placeholders: {invoice_no}, {customer_name}, {grand_total}, {invoice_url}, {company_name}, {invoice_date}, {due_date}, {status}, {outlet_name}" data-ar="المتغيرات: {invoice_no} و {customer_name} و {grand_total} و {invoice_url} و {company_name} و {invoice_date} و {due_date} و {status} و {outlet_name}">Placeholders: <code>{invoice_no}</code> <code>{customer_name}</code> <code>{grand_total}</code> <code>{invoice_url}</code> <code>{company_name}</code> <code>{invoice_date}</code> <code>{due_date}</code> <code>{status}</code> <code>{outlet_name}</code></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="col-12 col-xl-6">
|
||
<div class="border rounded-4 p-4 h-100 bg-light bg-opacity-50">
|
||
<div class="d-flex align-items-start justify-content-between gap-2 mb-3">
|
||
<div>
|
||
<h3 class="h6 fw-bold mb-1" data-en="Daily Summary Report" data-ar="تقرير الملخص اليومي">Daily Summary Report</h3>
|
||
<p class="text-muted small mb-0" data-en="Store the WhatsApp recap template, target numbers, and preferred report time" data-ar="احفظ قالب ملخص واتساب والأرقام المستهدفة ووقت التقرير المفضل">Store the WhatsApp recap template, target numbers, and preferred report time</p>
|
||
</div>
|
||
<span class="badge rounded-pill <?= ($data['settings']['wablas_daily_summary_enabled'] ?? '0') === '1' ? 'bg-success bg-opacity-10 text-success' : 'text-bg-light border' ?> px-3 py-2">
|
||
<?= ($data['settings']['wablas_daily_summary_enabled'] ?? '0') === '1' ? 'Enabled' : 'Disabled' ?>
|
||
</span>
|
||
</div>
|
||
<div class="row g-3">
|
||
<div class="col-md-4">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Status" data-ar="الحالة">Status</label>
|
||
<select name="settings[wablas_daily_summary_enabled]" class="form-select">
|
||
<option value="0" <?= ($data['settings']['wablas_daily_summary_enabled'] ?? '0') === '0' ? 'selected' : '' ?>>Disabled</option>
|
||
<option value="1" <?= ($data['settings']['wablas_daily_summary_enabled'] ?? '0') === '1' ? 'selected' : '' ?>>Enabled</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-md-8">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Send Time" data-ar="وقت الإرسال">Send Time</label>
|
||
<input type="time" name="settings[wablas_daily_summary_time]" class="form-control" value="<?= htmlspecialchars($data['settings']['wablas_daily_summary_time'] ?? '20:00') ?>">
|
||
<div class="form-text" data-en="Set the daily report delivery time. Default is 20:00 if left empty." data-ar="حدد وقت إرسال التقرير اليومي. الافتراضي هو 20:00 إذا تُرك الحقل فارغًا.">Set the daily report delivery time. Default is 20:00 if left empty.</div>
|
||
</div>
|
||
<div class="col-12">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Recipient Numbers" data-ar="أرقام المستلمين">Recipient Numbers</label>
|
||
<textarea name="settings[wablas_daily_summary_numbers]" class="form-control" rows="3" placeholder="+96890000000 +96891111111"><?= htmlspecialchars($data['settings']['wablas_daily_summary_numbers'] ?? '') ?></textarea>
|
||
<div class="form-text" data-en="Use one number per line or separate numbers with commas. Include the country code." data-ar="استخدم رقمًا واحدًا في كل سطر أو افصل الأرقام بفواصل. ضمّن رمز الدولة.">Use one number per line or separate numbers with commas. Include the country code.</div>
|
||
</div>
|
||
<div class="col-12">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Daily Summary Template" data-ar="قالب الملخص اليومي">Daily Summary Template</label>
|
||
<textarea name="settings[wablas_daily_summary_template]" class="form-control" rows="6" placeholder="Daily summary {report_date}: invoices {invoice_count}, sales {sales_total}, cash {cash_total}, card {card_total}"><?= htmlspecialchars($data['settings']['wablas_daily_summary_template'] ?? '') ?></textarea>
|
||
<div class="form-text" data-en="Placeholders: {report_date}, {report_time}, {invoice_count}, {sales_total}, {paid_total}, {cash_total}, {card_total}, {due_total}, {company_name}" data-ar="المتغيرات: {report_date} و {report_time} و {invoice_count} و {sales_total} و {paid_total} و {cash_total} و {card_total} و {due_total} و {company_name}">Placeholders: <code>{report_date}</code> <code>{report_time}</code> <code>{invoice_count}</code> <code>{sales_total}</code> <code>{paid_total}</code> <code>{cash_total}</code> <code>{card_total}</code> <code>{due_total}</code> <code>{company_name}</code></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="alert alert-light border rounded-4 mt-4 mb-0 small">
|
||
<div class="fw-semibold mb-1" data-en="Scheduling note" data-ar="ملاحظة الجدولة">Scheduling note</div>
|
||
<div class="text-muted mb-0" data-en="Invoice notifications are now queued from the sales workflow, and daily summaries are queued/sent by cron_wablas.php using the enable/disable switches above. Run the cron script every minute so due WhatsApp messages are dispatched automatically." data-ar="أصبحت إشعارات الفواتير تُضاف الآن إلى قائمة الانتظار من سير عمل المبيعات، كما تتم جدولة/إرسال الملخص اليومي عبر الملف cron_wablas.php باستخدام مفاتيح التفعيل والتعطيل أعلاه. شغّل مهمة cron كل دقيقة لإرسال رسائل واتساب المستحقة تلقائيًا.">Invoice notifications are now queued from the sales workflow, and daily summaries are queued/sent by cron_wablas.php using the enable/disable switches above. Run the cron script every minute so due WhatsApp messages are dispatched automatically.</div>
|
||
</div>
|
||
|
||
<div class="card border-0 bg-light rounded-4 mt-4 shadow-sm overflow-hidden">
|
||
<div class="card-body p-4">
|
||
<div class="d-flex flex-column flex-lg-row justify-content-between align-items-lg-center gap-3 mb-3">
|
||
<div>
|
||
<h3 class="h6 fw-bold mb-1" data-en="Wablas Manual Tools" data-ar="أدوات Wablas اليدوية">Wablas Manual Tools</h3>
|
||
<p class="text-muted small mb-0" data-en="Use these controls to send a test WhatsApp or run the due queue immediately without waiting for cron." data-ar="استخدم هذه الأدوات لإرسال رسالة واتساب تجريبية أو تشغيل قائمة الانتظار المستحقة فورًا دون انتظار مهمة cron.">Use these controls to send a test WhatsApp or run the due queue immediately without waiting for cron.</p>
|
||
</div>
|
||
<a href="<?= htmlspecialchars(page_url('logs')) ?>" class="btn btn-outline-secondary btn-sm rounded-pill px-3">
|
||
<i class="bi bi-clock-history me-1"></i>
|
||
<span data-en="View Dispatch Logs" data-ar="عرض سجل الإرسال">View Dispatch Logs</span>
|
||
</a>
|
||
</div>
|
||
|
||
<div class="alert alert-warning border-0 py-2 small mb-4">
|
||
<div class="fw-semibold mb-1" data-en="Save before testing" data-ar="احفظ قبل الاختبار">Save before testing</div>
|
||
<div class="mb-0" data-en="Manual tools use the saved Wablas credentials and templates. If you just changed the gateway settings above, click Save All Changes first." data-ar="تستخدم الأدوات اليدوية بيانات اعتماد Wablas والقوالب المحفوظة. إذا غيّرت إعدادات البوابة أعلاه الآن، فانقر أولاً على حفظ جميع التغييرات.">Manual tools use the saved Wablas credentials and templates. If you just changed the gateway settings above, click Save All Changes first.</div>
|
||
</div>
|
||
|
||
<div class="row g-4 align-items-stretch">
|
||
<div class="col-lg-7">
|
||
<label class="form-label text-muted small fw-semibold" data-en="Test Recipient Numbers" data-ar="أرقام المستلمين للاختبار">Test Recipient Numbers</label>
|
||
<textarea name="wablas_test_numbers" class="form-control" rows="3" placeholder="+96890000000 +96891111111"></textarea>
|
||
<div class="form-text" data-en="Use one number per line or separate numbers with commas. The saved default country code is applied when needed." data-ar="استخدم رقمًا واحدًا في كل سطر أو افصل الأرقام بفواصل. سيتم تطبيق رمز الدولة الافتراضي المحفوظ عند الحاجة.">Use one number per line or separate numbers with commas. The saved default country code is applied when needed.</div>
|
||
|
||
<label class="form-label text-muted small fw-semibold mt-3" data-en="Test Message" data-ar="رسالة الاختبار">Test Message</label>
|
||
<textarea name="wablas_test_message" class="form-control" rows="4" placeholder="This is a test WhatsApp message from the admin panel."></textarea>
|
||
<div class="form-text" data-en="This sends immediately and writes the result to the Wablas dispatch log." data-ar="يتم الإرسال فورًا ويتم تسجيل النتيجة في سجل إرسال Wablas.">This sends immediately and writes the result to the Wablas dispatch log.</div>
|
||
|
||
<button type="submit" name="wablas_send_test" value="1" formnovalidate class="btn btn-success rounded-pill px-4 mt-3">
|
||
<i class="bi bi-send me-2"></i>
|
||
<span data-en="Send Test WhatsApp" data-ar="إرسال واتساب تجريبي">Send Test WhatsApp</span>
|
||
</button>
|
||
</div>
|
||
|
||
<div class="col-lg-5">
|
||
<div class="card border-0 shadow-sm h-100 rounded-4">
|
||
<div class="card-body p-4 d-flex flex-column">
|
||
<div class="rounded-circle bg-primary bg-opacity-10 text-primary p-2 align-self-start mb-3"><i class="bi bi-lightning-charge"></i></div>
|
||
<h4 class="h6 fw-bold mb-2" data-en="Run Due Queue Now" data-ar="تشغيل قائمة الانتظار المستحقة الآن">Run Due Queue Now</h4>
|
||
<p class="text-muted small mb-3" data-en="This checks whether today’s daily summary is already due, then processes pending/failed Wablas jobs immediately." data-ar="يتحقق هذا مما إذا كان الملخص اليومي لليوم مستحقًا بالفعل، ثم يعالج مهام Wablas المعلقة/الفاشلة فورًا.">This checks whether today’s daily summary is already due, then processes pending/failed Wablas jobs immediately.</p>
|
||
<ul class="small text-muted ps-3 mb-4">
|
||
<li data-en="Respects the master Wablas enable/disable switch" data-ar="يحترم مفتاح تفعيل/تعطيل Wablas الرئيسي">Respects the master Wablas enable/disable switch</li>
|
||
<li data-en="Keeps future-scheduled jobs pending until they are due" data-ar="يبقي المهام المجدولة للمستقبل معلقة حتى يحين وقتها">Keeps future-scheduled jobs pending until they are due</li>
|
||
<li data-en="Useful for testing invoices and same-day summaries" data-ar="مفيد لاختبار الفواتير والملخصات اليومية لنفس اليوم">Useful for testing invoices and same-day summaries</li>
|
||
</ul>
|
||
<button type="submit" name="wablas_run_due_now" value="1" formnovalidate class="btn btn-outline-primary rounded-pill px-4 mt-auto">
|
||
<i class="bi bi-play-circle me-2"></i>
|
||
<span data-en="Run Due Queue Now" data-ar="تشغيل قائمة الانتظار المستحقة الآن">Run Due Queue Now</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="d-flex flex-column flex-md-row justify-content-end gap-2 pt-4 mt-4 border-top">
|
||
<button type="submit" name="update_settings" class="btn btn-primary btn-lg rounded-pill px-5 shadow-sm align-self-md-end">
|
||
<i class="bi bi-check-lg me-2"></i>
|
||
<span data-en="Save All Changes" data-ar="حفظ جميع التغييرات">Save All Changes</span>
|
||
</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
document.addEventListener('DOMContentLoaded', function () {
|
||
var nameInput = document.getElementById('license-app-name');
|
||
var slugInput = document.getElementById('license-app-slug');
|
||
var suggestButton = document.getElementById('suggest-license-slug');
|
||
var activeTabInput = document.getElementById('settings-active-tab');
|
||
var tabButtons = document.querySelectorAll('#settingsTabs [data-bs-toggle="tab"]');
|
||
|
||
if (nameInput && slugInput && suggestButton) {
|
||
var slugWasExplicit = slugInput.dataset.explicit === '1';
|
||
var slugify = function (value) {
|
||
return String(value || '')
|
||
.toLowerCase()
|
||
.trim()
|
||
.replace(/[^a-z0-9]+/g, '-')
|
||
.replace(/^-+|-+$/g, '');
|
||
};
|
||
|
||
nameInput.addEventListener('input', function () {
|
||
if (!slugWasExplicit || slugInput.value.trim() === '') {
|
||
slugInput.value = slugify(nameInput.value);
|
||
}
|
||
});
|
||
|
||
slugInput.addEventListener('input', function () {
|
||
slugWasExplicit = slugInput.value.trim() !== '';
|
||
slugInput.dataset.explicit = slugWasExplicit ? '1' : '0';
|
||
});
|
||
|
||
suggestButton.addEventListener('click', function () {
|
||
slugInput.value = slugify(nameInput.value);
|
||
slugWasExplicit = slugInput.value.trim() !== '';
|
||
slugInput.dataset.explicit = slugWasExplicit ? '1' : '0';
|
||
slugInput.focus();
|
||
});
|
||
}
|
||
|
||
tabButtons.forEach(function (button) {
|
||
button.addEventListener('shown.bs.tab', function (event) {
|
||
var tabKey = event.target.getAttribute('data-tab-key') || 'company';
|
||
if (activeTabInput) {
|
||
activeTabInput.value = tabKey;
|
||
}
|
||
try {
|
||
var currentUrl = new URL(window.location.href);
|
||
currentUrl.searchParams.set('tab', tabKey);
|
||
window.history.replaceState({}, '', currentUrl.toString());
|
||
} catch (error) {
|
||
// Ignore URL update errors and keep the tab interaction working.
|
||
}
|
||
});
|
||
});
|
||
|
||
var activeButton = document.querySelector('#settingsTabs .nav-link.active');
|
||
if (activeButton && activeTabInput) {
|
||
activeTabInput.value = activeButton.getAttribute('data-tab-key') || 'company';
|
||
}
|
||
});
|
||
</script>
|