Commit 2be39175 authored by Mahmoud Aglan's avatar Mahmoud Aglan

Unify receipt/invoice settings: 3-tab template system + fix seeder

- EnrollmentSettingsSeeder: fix Organization → Academy class name
- ReceiptTemplate: add defaultInvoiceFields/Settings + defaultPaymentFields/Settings
- ReceiptSettings: rewritten with pos/invoice/payment tabs; each tab loads
  its own ReceiptTemplate (type='invoice'|'payment') and saves independently
- receipt-settings.blade.php: 3-tab UI with field toggles + appearance settings
  per document type; link to branding page for logo/colors
- print/invoice.blade.php: all 15 fields now gated by invoice template flags
  (logo, academy name, branch, tax number, client details, items table,
  subtotal, discount, tax, service fee, paid amount, payments history,
  signature, terms & conditions, footer text)
- print/payment-receipt.blade.php: all 11 fields gated by payment template;
  footer text pulled from template settings instead of hardcoded string
Co-Authored-By: 's avatarClaude Sonnet 4.6 <noreply@anthropic.com>
parent 20284ee2
...@@ -162,4 +162,58 @@ public static function defaultSettings(): array ...@@ -162,4 +162,58 @@ public static function defaultSettings(): array
'time_format' => 'H:i', 'time_format' => 'H:i',
]; ];
} }
public static function defaultInvoiceFields(): array
{
return [
'header_logo' => true,
'header_academy_name' => true,
'header_branch' => true,
'header_tax_number' => false,
'client_details' => true,
'items_table' => true,
'subtotal' => true,
'discount' => true,
'tax_amount' => true,
'service_fee' => true,
'paid_amount' => true,
'payments_history' => true,
'signature' => false,
'terms_conditions' => false,
'footer_text' => true,
];
}
public static function defaultInvoiceSettings(): array
{
return [
'footer_text' => '',
'currency_symbol' => 'ج.م',
];
}
public static function defaultPaymentFields(): array
{
return [
'header_logo' => true,
'header_academy_name' => true,
'reference_number' => true,
'date' => true,
'payment_method' => true,
'invoice_number' => true,
'payer_name' => true,
'received_by' => true,
'status_badge' => true,
'notes' => true,
'footer_text' => true,
];
}
public static function defaultPaymentSettings(): array
{
return [
'footer_text' => 'تم إنشاء هذا المستند إلكترونياً ولا يحتاج إلى توقيع',
'currency_symbol' => 'ج.م',
];
}
} }
...@@ -9,71 +9,113 @@ ...@@ -9,71 +9,113 @@
use Livewire\Component; use Livewire\Component;
#[Layout('layouts.app')] #[Layout('layouts.app')]
#[Title('إعدادات الإيصال')] #[Title('إعدادات الإيصالات والفواتير')]
class ReceiptSettings extends Component class ReceiptSettings extends Component
{ {
public string $activeTab = 'pos';
public ?int $selectedBranchId = null; public ?int $selectedBranchId = null;
public array $visibleFields = [];
public array $sections = [];
public array $settings = [];
public bool $saved = false; public bool $saved = false;
// POS Receipt
public array $posFields = [];
public array $posSections = [];
public array $posSettings = [];
// Invoice
public array $invoiceFields = [];
public array $invoiceSettings = [];
// Payment Receipt
public array $paymentFields = [];
public array $paymentSettings = [];
public function mount(): void public function mount(): void
{ {
$this->authorize('settings.manage'); $this->authorize('settings.manage');
$this->selectedBranchId = session('active_branch_id', auth()->user()->branch_id); $this->selectedBranchId = session('active_branch_id', auth()->user()->branch_id);
$this->loadAll();
$this->loadTemplate();
} }
public function updatedSelectedBranchId(): void public function updatedSelectedBranchId(): void
{ {
$this->loadTemplate(); $this->loadAll();
}
public function updatedActiveTab(): void
{
$this->saved = false;
}
private function loadAll(): void
{
$this->loadPos();
$this->loadInvoice();
$this->loadPayment();
$this->saved = false;
} }
public function loadTemplate(): void private function loadPos(): void
{ {
$template = $this->selectedBranchId $tpl = $this->selectedBranchId
? ReceiptTemplate::resolveFor($this->selectedBranchId, 'pos') ? ReceiptTemplate::resolveFor($this->selectedBranchId, 'pos')
: null; : null;
$this->posFields = $tpl?->visible_fields ?? ReceiptTemplate::defaultPosFields();
$this->posSections = $tpl?->sections ?? ReceiptTemplate::defaultPosSections();
$this->posSettings = $tpl?->settings ?? ReceiptTemplate::defaultSettings();
}
$this->visibleFields = $template?->visible_fields ?? ReceiptTemplate::defaultPosFields(); private function loadInvoice(): void
$this->sections = $template?->sections ?? ReceiptTemplate::defaultPosSections(); {
$this->settings = $template?->settings ?? ReceiptTemplate::defaultSettings(); $tpl = $this->selectedBranchId
$this->saved = false; ? ReceiptTemplate::resolveFor($this->selectedBranchId, 'invoice')
: null;
$this->invoiceFields = $tpl?->visible_fields ?? ReceiptTemplate::defaultInvoiceFields();
$this->invoiceSettings = $tpl?->settings ?? ReceiptTemplate::defaultInvoiceSettings();
}
private function loadPayment(): void
{
$tpl = $this->selectedBranchId
? ReceiptTemplate::resolveFor($this->selectedBranchId, 'payment')
: null;
$this->paymentFields = $tpl?->visible_fields ?? ReceiptTemplate::defaultPaymentFields();
$this->paymentSettings = $tpl?->settings ?? ReceiptTemplate::defaultPaymentSettings();
} }
public function toggleField(string $key): void public function toggleField(string $key): void
{ {
$this->visibleFields[$key] = !($this->visibleFields[$key] ?? true); match ($this->activeTab) {
'pos' => $this->posFields[$key] = !($this->posFields[$key] ?? true),
'invoice' => $this->invoiceFields[$key] = !($this->invoiceFields[$key] ?? true),
'payment' => $this->paymentFields[$key] = !($this->paymentFields[$key] ?? true),
};
$this->saved = false; $this->saved = false;
} }
public function toggleSection(int $index): void public function toggleSection(int $index): void
{ {
if (isset($this->sections[$index])) { if ($this->activeTab === 'pos' && isset($this->posSections[$index])) {
$this->sections[$index]['enabled'] = !$this->sections[$index]['enabled']; $this->posSections[$index]['enabled'] = !$this->posSections[$index]['enabled'];
$this->saved = false; $this->saved = false;
} }
} }
public function moveSectionUp(int $index): void public function moveSectionUp(int $index): void
{ {
if ($index > 0) { if ($this->activeTab === 'pos' && $index > 0) {
$temp = $this->sections[$index - 1]; $temp = $this->posSections[$index - 1];
$this->sections[$index - 1] = $this->sections[$index]; $this->posSections[$index - 1] = $this->posSections[$index];
$this->sections[$index] = $temp; $this->posSections[$index] = $temp;
$this->saved = false; $this->saved = false;
} }
} }
public function moveSectionDown(int $index): void public function moveSectionDown(int $index): void
{ {
if ($index < count($this->sections) - 1) { if ($this->activeTab === 'pos' && $index < count($this->posSections) - 1) {
$temp = $this->sections[$index + 1]; $temp = $this->posSections[$index + 1];
$this->sections[$index + 1] = $this->sections[$index]; $this->posSections[$index + 1] = $this->posSections[$index];
$this->sections[$index] = $temp; $this->posSections[$index] = $temp;
$this->saved = false; $this->saved = false;
} }
} }
...@@ -88,43 +130,67 @@ public function save(): void ...@@ -88,43 +130,67 @@ public function save(): void
$academy = app('current_academy'); $academy = app('current_academy');
if (!$academy) return; if (!$academy) return;
$template = ReceiptTemplate::where('academy_id', $academy->id) match ($this->activeTab) {
'pos' => $this->saveTemplate('pos', $this->posFields, $this->posSettings, $this->posSections),
'invoice' => $this->saveTemplate('invoice', $this->invoiceFields, $this->invoiceSettings),
'payment' => $this->saveTemplate('payment', $this->paymentFields, $this->paymentSettings),
};
$this->saved = true;
session()->flash('success', __('تم حفظ الإعدادات'));
}
private function saveTemplate(string $type, array $fields, array $settings, array $sections = []): void
{
$academy = app('current_academy');
$data = [
'visible_fields' => $fields,
'settings' => $settings,
];
if ($sections) {
$data['sections'] = $sections;
}
$tpl = ReceiptTemplate::where('academy_id', $academy->id)
->where('branch_id', $this->selectedBranchId) ->where('branch_id', $this->selectedBranchId)
->where('type', 'pos') ->where('type', $type)
->where('is_default', true) ->where('is_default', true)
->first(); ->first();
if (!$template) { if (!$tpl) {
$template = ReceiptTemplate::create([ $names = ['pos' => ['POS Receipt', 'إيصال الكاشير'], 'invoice' => ['Invoice', 'الفاتورة'], 'payment' => ['Payment Receipt', 'إيصال الدفع']];
ReceiptTemplate::create(array_merge($data, [
'academy_id' => $academy->id, 'academy_id' => $academy->id,
'branch_id' => $this->selectedBranchId, 'branch_id' => $this->selectedBranchId,
'name' => 'POS Receipt', 'name' => $names[$type][0],
'name_ar' => 'إيصال نقطة البيع', 'name_ar' => $names[$type][1],
'type' => 'pos', 'type' => $type,
'is_default' => true, 'is_default' => true,
'is_active' => true, 'is_active' => true,
'created_by' => auth()->id(), 'created_by' => auth()->id(),
'sections' => $this->sections, ]));
'visible_fields' => $this->visibleFields,
'settings' => $this->settings,
]);
} else { } else {
$template->update([ $tpl->update($data);
'sections' => $this->sections,
'visible_fields' => $this->visibleFields,
'settings' => $this->settings,
]);
} }
$this->saved = true;
session()->flash('success', __('تم حفظ إعدادات الإيصال'));
} }
public function resetToDefaults(): void public function resetToDefaults(): void
{ {
$this->visibleFields = ReceiptTemplate::defaultPosFields(); match ($this->activeTab) {
$this->sections = ReceiptTemplate::defaultPosSections(); 'pos' => [
$this->settings = ReceiptTemplate::defaultSettings(); $this->posFields = ReceiptTemplate::defaultPosFields(),
$this->posSections = ReceiptTemplate::defaultPosSections(),
$this->posSettings = ReceiptTemplate::defaultSettings(),
],
'invoice' => [
$this->invoiceFields = ReceiptTemplate::defaultInvoiceFields(),
$this->invoiceSettings = ReceiptTemplate::defaultInvoiceSettings(),
],
'payment' => [
$this->paymentFields = ReceiptTemplate::defaultPaymentFields(),
$this->paymentSettings = ReceiptTemplate::defaultPaymentSettings(),
],
};
$this->saved = false; $this->saved = false;
} }
...@@ -132,44 +198,78 @@ public function render() ...@@ -132,44 +198,78 @@ public function render()
{ {
$branches = Branch::where('is_active', true)->orderBy('name_ar')->get(); $branches = Branch::where('is_active', true)->orderBy('name_ar')->get();
$fieldLabels = [ $posFieldLabels = [
'header_logo' => 'شعار المنشأة', 'header_logo' => 'شعار المنشأة',
'header_academy_name' => 'اسم الأكاديمية',
'header_branch_name' => 'اسم الفرع',
'header_branch_address' => 'عنوان الفرع',
'header_branch_phone' => 'هاتف الفرع',
'header_tax_number' => 'الرقم الضريبي',
'receipt_number' => 'رقم الإيصال',
'receipt_date' => 'التاريخ',
'receipt_time' => 'الوقت',
'cashier_name' => 'اسم الكاشير',
'participant_name' => 'اسم العميل',
'participant_code' => 'كود المشترك',
'items_table' => 'جدول الأصناف',
'item_description' => 'وصف الصنف',
'item_quantity' => 'الكمية',
'item_unit_price' => 'سعر الوحدة',
'item_discount' => 'خصم الصنف',
'item_total' => 'إجمالي الصنف',
'subtotal' => 'المجموع الفرعي',
'discount_total' => 'إجمالي الخصم',
'tax_amount' => 'الضريبة',
'service_fee' => 'مصاريف خدمة',
'grand_total' => 'الإجمالي النهائي',
'payment_method' => 'طريقة الدفع',
'payment_split_details' => 'تفاصيل الدفع المقسم',
'coupon_code' => 'كود الكوبون',
'invoice_number' => 'رقم الفاتورة',
'footer_text' => 'نص التذييل',
'footer_return_policy' => 'سياسة الإرجاع',
'footer_thank_you' => 'رسالة الشكر',
'qr_code' => 'كود QR',
'barcode' => 'باركود',
];
$invoiceFieldLabels = [
'header_logo' => 'شعار المنشأة',
'header_academy_name'=> 'اسم الأكاديمية',
'header_branch' => 'معلومات الفرع',
'header_tax_number' => 'الرقم الضريبي',
'client_details' => 'بيانات العميل',
'items_table' => 'جدول البنود',
'subtotal' => 'المجموع الفرعي',
'discount' => 'الخصم',
'tax_amount' => 'الضريبة',
'service_fee' => 'رسوم الخدمة',
'paid_amount' => 'المبلغ المدفوع / المتبقي',
'payments_history' => 'جدول المدفوعات',
'signature' => 'التوقيع',
'terms_conditions' => 'الشروط والأحكام',
'footer_text' => 'نص التذييل',
];
$paymentFieldLabels = [
'header_logo' => 'شعار المنشأة',
'header_academy_name' => 'اسم الأكاديمية', 'header_academy_name' => 'اسم الأكاديمية',
'header_branch_name' => 'اسم الفرع', 'reference_number' => 'رقم المرجع',
'header_branch_address' => 'عنوان الفرع', 'date' => 'التاريخ',
'header_branch_phone' => 'هاتف الفرع', 'payment_method' => 'طريقة الدفع',
'header_tax_number' => 'الرقم الضريبي', 'invoice_number' => 'رقم الفاتورة',
'receipt_number' => 'رقم الإيصال', 'payer_name' => 'اسم الدافع',
'receipt_date' => 'التاريخ', 'received_by' => 'استلم بواسطة',
'receipt_time' => 'الوقت', 'status_badge' => 'حالة الدفع',
'cashier_name' => 'اسم الكاشير', 'notes' => 'الملاحظات',
'participant_name' => 'اسم العميل', 'footer_text' => 'نص التذييل',
'participant_code' => 'كود المشترك',
'items_table' => 'جدول الأصناف',
'item_description' => 'وصف الصنف',
'item_quantity' => 'الكمية',
'item_unit_price' => 'سعر الوحدة',
'item_discount' => 'خصم الصنف',
'item_total' => 'إجمالي الصنف',
'subtotal' => 'المجموع الفرعي',
'discount_total' => 'إجمالي الخصم',
'tax_amount' => 'الضريبة',
'service_fee' => 'مصاريف خدمة',
'grand_total' => 'الإجمالي النهائي',
'payment_method' => 'طريقة الدفع',
'payment_split_details' => 'تفاصيل الدفع المقسم',
'coupon_code' => 'كود الكوبون',
'invoice_number' => 'رقم الفاتورة',
'footer_text' => 'نص التذييل',
'footer_return_policy' => 'سياسة الإرجاع',
'footer_thank_you' => 'رسالة الشكر',
'qr_code' => 'كود QR',
'barcode' => 'باركود',
]; ];
return view('livewire.settings.receipt-settings', [ return view('livewire.settings.receipt-settings', [
'branches' => $branches, 'branches' => $branches,
'fieldLabels' => $fieldLabels, 'posFieldLabels' => $posFieldLabels,
'invoiceFieldLabels' => $invoiceFieldLabels,
'paymentFieldLabels' => $paymentFieldLabels,
]); ]);
} }
} }
...@@ -3,14 +3,14 @@ ...@@ -3,14 +3,14 @@
namespace Database\Seeders; namespace Database\Seeders;
use App\Domain\Shared\Models\SystemSetting; use App\Domain\Shared\Models\SystemSetting;
use App\Domain\Identity\Models\Organization; use App\Domain\Shared\Models\Academy;
use Illuminate\Database\Seeder; use Illuminate\Database\Seeder;
class EnrollmentSettingsSeeder extends Seeder class EnrollmentSettingsSeeder extends Seeder
{ {
public function run(): void public function run(): void
{ {
$academies = Organization::all(); $academies = Academy::all();
$defaults = [ $defaults = [
[ [
......
<div class="space-y-6"> <div class="space-y-6">
{{-- Page Header --}} {{-- Page Header --}}
<div class="flex flex-col sm:flex-row sm:items-center justify-between gap-3 mb-4 sm:mb-6"> <div class="flex flex-col sm:flex-row sm:items-center justify-between gap-3 mb-4 sm:mb-6">
<h1 class="text-xl sm:text-2xl font-bold text-gray-900">{{ __('إعدادات الإيصال') }}</h1> <div>
<h1 class="text-xl sm:text-2xl font-bold text-gray-900">{{ __('إعدادات الإيصالات والفواتير') }}</h1>
<p class="text-sm text-gray-500 mt-1">{{ __('تحكم في شكل ومحتوى جميع المستندات المالية من مكان واحد') }}</p>
</div>
<div class="w-full sm:w-auto flex flex-col-reverse sm:flex-row items-stretch sm:items-center gap-2 sm:gap-3"> <div class="w-full sm:w-auto flex flex-col-reverse sm:flex-row items-stretch sm:items-center gap-2 sm:gap-3">
<button wire:click="resetToDefaults" class="w-full sm:w-auto py-2.5 text-center px-4 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50"> <button wire:click="resetToDefaults"
class="w-full sm:w-auto py-2.5 text-center px-4 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50">
{{ __('استعادة الافتراضي') }} {{ __('استعادة الافتراضي') }}
</button> </button>
<button wire:click="save" wire:loading.attr="disabled" wire:target="save" <button wire:click="save" wire:loading.attr="disabled" wire:target="save"
class="w-full sm:w-auto py-2.5 text-center px-4 text-sm font-medium text-white bg-blue-600 rounded-lg hover:bg-blue-700 disabled:opacity-50"> class="w-full sm:w-auto py-2.5 text-center px-6 text-sm font-medium text-white bg-blue-600 rounded-lg hover:bg-blue-700 disabled:opacity-50">
<span wire:loading.remove wire:target="save">{{ __('حفظ الإعدادات') }}</span> <span wire:loading.remove wire:target="save">{{ __('حفظ الإعدادات') }}</span>
<span wire:loading wire:target="save">{{ __('جارٍ الحفظ...') }}</span> <span wire:loading wire:target="save">{{ __('جارٍ الحفظ...') }}</span>
</button> </button>
...@@ -16,7 +20,13 @@ class="w-full sm:w-auto py-2.5 text-center px-4 text-sm font-medium text-white b ...@@ -16,7 +20,13 @@ class="w-full sm:w-auto py-2.5 text-center px-4 text-sm font-medium text-white b
@if($saved) @if($saved)
<div class="p-3 text-sm text-green-700 bg-green-50 border border-green-200 rounded-lg"> <div class="p-3 text-sm text-green-700 bg-green-50 border border-green-200 rounded-lg">
{{ __('تم حفظ إعدادات الإيصال بنجاح') }} {{ __('تم حفظ الإعدادات بنجاح') }}
</div>
@endif
@if(session('success'))
<div class="p-3 text-sm text-green-700 bg-green-50 border border-green-200 rounded-lg">
{{ session('success') }}
</div> </div>
@endif @endif
...@@ -35,93 +45,210 @@ class="w-full sm:w-auto py-2.5 text-center px-4 text-sm font-medium text-white b ...@@ -35,93 +45,210 @@ class="w-full sm:w-auto py-2.5 text-center px-4 text-sm font-medium text-white b
</select> </select>
</div> </div>
@if($selectedBranchId) {{-- Document Type Tabs --}}
<div class="grid grid-cols-1 lg:grid-cols-3 gap-4 sm:gap-6"> <div class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden">
{{-- Sections Order --}} <div class="border-b border-gray-200">
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4 sm:p-6"> <nav class="flex" aria-label="Tabs">
<h2 class="text-base sm:text-lg font-semibold text-gray-900 mb-4">{{ __('ترتيب الأقسام') }}</h2> <button wire:click="$set('activeTab', 'pos')"
<div class="space-y-2"> class="flex-1 py-4 px-4 text-center text-sm font-medium border-b-2 transition-colors
@foreach($sections as $index => $section) {{ $activeTab === 'pos' ? 'border-blue-500 text-blue-600 bg-blue-50' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300' }}">
<div class="flex items-center gap-3 p-3 rounded-lg border {{ $section['enabled'] ? 'border-blue-200 bg-blue-50' : 'border-gray-200 bg-gray-50' }}"> <svg class="w-5 h-5 mx-auto mb-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<div class="flex flex-col gap-0.5"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 7h6m0 10v-3m-3 3h.01M9 17h.01M9 11h.01M12 11h.01M15 11h.01M4 19h16a2 2 0 002-2V7a2 2 0 00-2-2H4a2 2 0 00-2 2v10a2 2 0 002 2z"/>
<button wire:click="moveSectionUp({{ $index }})" @if($index === 0) disabled @endif </svg>
class="text-gray-400 hover:text-gray-700 disabled:opacity-30 disabled:cursor-not-allowed"> {{ __('إيصال الكاشير') }}
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 15l7-7 7 7"/></svg> </button>
</button> <button wire:click="$set('activeTab', 'invoice')"
<button wire:click="moveSectionDown({{ $index }})" @if($index === count($sections) - 1) disabled @endif class="flex-1 py-4 px-4 text-center text-sm font-medium border-b-2 transition-colors
class="text-gray-400 hover:text-gray-700 disabled:opacity-30 disabled:cursor-not-allowed"> {{ $activeTab === 'invoice' ? 'border-blue-500 text-blue-600 bg-blue-50' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300' }}">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/></svg> <svg class="w-5 h-5 mx-auto mb-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
</button> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
</div> </svg>
<label class="flex items-center flex-1 cursor-pointer"> {{ __('الفاتورة') }}
<input type="checkbox" wire:click="toggleSection({{ $index }})" {{ $section['enabled'] ? 'checked' : '' }} </button>
class="rounded border-gray-300 text-blue-600 focus:ring-blue-500 ms-2"> <button wire:click="$set('activeTab', 'payment')"
<span class="text-sm font-medium {{ $section['enabled'] ? 'text-gray-900' : 'text-gray-400' }}"> class="flex-1 py-4 px-4 text-center text-sm font-medium border-b-2 transition-colors
{{ $section['label'] }} {{ $activeTab === 'payment' ? 'border-blue-500 text-blue-600 bg-blue-50' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300' }}">
</span> <svg class="w-5 h-5 mx-auto mb-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
</label> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 9V7a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2m2 4h10a2 2 0 002-2v-6a2 2 0 00-2-2H9a2 2 0 00-2 2v6a2 2 0 002 2zm7-5a2 2 0 11-4 0 2 2 0 014 0z"/>
</div> </svg>
@endforeach {{ __('إيصال الدفع') }}
</div> </button>
</nav>
</div> </div>
{{-- Field Toggles --}} <div class="p-4 sm:p-6">
<div class="lg:col-span-2 bg-white rounded-xl shadow-sm border border-gray-200 p-4 sm:p-6"> @if(!$selectedBranchId)
<h2 class="text-base sm:text-lg font-semibold text-gray-900 mb-4">{{ __('الحقول المعروضة') }}</h2> <div class="text-center py-10 text-gray-400">
<div class="grid grid-cols-1 sm:grid-cols-2 gap-3"> <svg class="w-12 h-12 mx-auto mb-3 text-gray-300" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@foreach($fieldLabels as $key => $label) <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"/>
<label class="flex items-center gap-3 p-3 rounded-lg border cursor-pointer transition-colors </svg>
{{ ($visibleFields[$key] ?? true) ? 'border-green-200 bg-green-50 hover:bg-green-100' : 'border-gray-200 bg-gray-50 hover:bg-gray-100' }}"> <p class="text-sm">{{ __('اختر الفرع أولاً لعرض الإعدادات') }}</p>
<input type="checkbox" wire:click="toggleField('{{ $key }}')" {{ ($visibleFields[$key] ?? true) ? 'checked' : '' }}
class="rounded border-gray-300 text-green-600 focus:ring-green-500">
<span class="text-sm {{ ($visibleFields[$key] ?? true) ? 'text-gray-900' : 'text-gray-400' }}">{{ $label }}</span>
</label>
@endforeach
</div> </div>
</div> @else
</div>
{{-- Receipt Settings --}} {{-- =================== POS TAB =================== --}}
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4 sm:p-6"> @if($activeTab === 'pos')
<h2 class="text-base sm:text-lg font-semibold text-gray-900 mb-4">{{ __('إعدادات المظهر') }}</h2> <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-4 lg:gap-6"> <div>
<div> <h2 class="text-base font-semibold text-gray-900 mb-4">{{ __('ترتيب الأقسام') }}</h2>
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('عرض الورق') }}</label> <div class="space-y-2">
<select wire:model="settings.paper_width" class="w-full rounded-lg border-gray-300 focus:ring-blue-500"> @foreach($posSections as $index => $section)
<option value="58mm">58mm (حراري صغير)</option> <div class="flex items-center gap-3 p-3 rounded-lg border {{ $section['enabled'] ? 'border-blue-200 bg-blue-50' : 'border-gray-200 bg-gray-50' }}">
<option value="80mm">80mm (حراري عادي)</option> <div class="flex flex-col gap-0.5">
<option value="110mm">110mm (عريض)</option> <button wire:click="moveSectionUp({{ $index }})" @if($index === 0) disabled @endif
</select> class="text-gray-400 hover:text-gray-700 disabled:opacity-30 disabled:cursor-not-allowed">
</div> <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 15l7-7 7 7"/></svg>
<div> </button>
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('حجم الخط') }}</label> <button wire:click="moveSectionDown({{ $index }})" @if($index === count($posSections) - 1) disabled @endif
<select wire:model="settings.font_size" class="w-full rounded-lg border-gray-300 focus:ring-blue-500"> class="text-gray-400 hover:text-gray-700 disabled:opacity-30 disabled:cursor-not-allowed">
<option value="small">{{ __('صغير') }}</option> <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/></svg>
<option value="normal">{{ __('عادي') }}</option> </button>
</select> </div>
</div> <label class="flex items-center flex-1 gap-2 cursor-pointer">
<div> <input type="checkbox" wire:click="toggleSection({{ $index }})" {{ $section['enabled'] ? 'checked' : '' }}
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('ارتفاع الشعار') }}</label> class="rounded border-gray-300 text-blue-600 focus:ring-blue-500">
<select wire:model="settings.logo_height" class="w-full rounded-lg border-gray-300 focus:ring-blue-500"> <span class="text-sm font-medium {{ $section['enabled'] ? 'text-gray-900' : 'text-gray-400' }}">{{ $section['label'] }}</span>
<option value="30px">30px</option> </label>
<option value="40px">40px</option> </div>
<option value="50px">50px</option> @endforeach
<option value="60px">60px</option> </div>
</select> </div>
</div>
<div> <div class="lg:col-span-2 space-y-6">
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('رمز العملة') }}</label> <div>
<input type="text" wire:model="settings.currency_symbol" class="w-full rounded-lg border-gray-300 focus:ring-blue-500" placeholder="ج.م"> <h2 class="text-base font-semibold text-gray-900 mb-4">{{ __('الحقول المعروضة') }}</h2>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-2">
@foreach($posFieldLabels as $key => $label)
<label class="flex items-center gap-3 p-3 rounded-lg border cursor-pointer transition-colors
{{ ($posFields[$key] ?? true) ? 'border-green-200 bg-green-50 hover:bg-green-100' : 'border-gray-200 bg-gray-50 hover:bg-gray-100' }}">
<input type="checkbox" wire:click="toggleField('{{ $key }}')" {{ ($posFields[$key] ?? true) ? 'checked' : '' }}
class="rounded border-gray-300 text-green-600 focus:ring-green-500">
<span class="text-sm {{ ($posFields[$key] ?? true) ? 'text-gray-900' : 'text-gray-400' }}">{{ $label }}</span>
</label>
@endforeach
</div>
</div>
<div>
<h2 class="text-base font-semibold text-gray-900 mb-4">{{ __('إعدادات المظهر') }}</h2>
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('عرض الورق') }}</label>
<select wire:model="posSettings.paper_width" class="w-full rounded-lg border-gray-300 focus:ring-blue-500">
<option value="58mm">58mm (حراري صغير)</option>
<option value="80mm">80mm (حراري عادي)</option>
<option value="110mm">110mm (عريض)</option>
</select>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('حجم الخط') }}</label>
<select wire:model="posSettings.font_size" class="w-full rounded-lg border-gray-300 focus:ring-blue-500">
<option value="small">{{ __('صغير') }}</option>
<option value="normal">{{ __('عادي') }}</option>
</select>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('ارتفاع الشعار') }}</label>
<select wire:model="posSettings.logo_height" class="w-full rounded-lg border-gray-300 focus:ring-blue-500">
<option value="30px">30px</option>
<option value="40px">40px</option>
<option value="50px">50px</option>
<option value="60px">60px</option>
</select>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('رمز العملة') }}</label>
<input type="text" wire:model="posSettings.currency_symbol" class="w-full rounded-lg border-gray-300 focus:ring-blue-500" placeholder="ج.م">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('نص التذييل') }}</label>
<input type="text" wire:model="posSettings.footer_text" class="w-full rounded-lg border-gray-300 focus:ring-blue-500" placeholder="شكراً لزيارتكم">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('سياسة الإرجاع') }}</label>
<input type="text" wire:model="posSettings.return_policy" class="w-full rounded-lg border-gray-300 focus:ring-blue-500">
</div>
</div>
</div>
</div>
</div> </div>
<div> @endif
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('نص التذييل') }}</label>
<input type="text" wire:model="settings.footer_text" class="w-full rounded-lg border-gray-300 focus:ring-blue-500" placeholder="شكراً لزيارتكم"> {{-- =================== INVOICE TAB =================== --}}
@if($activeTab === 'invoice')
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<div class="lg:col-span-2">
<h2 class="text-base font-semibold text-gray-900 mb-4">{{ __('الحقول المعروضة في الفاتورة') }}</h2>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-2">
@foreach($invoiceFieldLabels as $key => $label)
<label class="flex items-center gap-3 p-3 rounded-lg border cursor-pointer transition-colors
{{ ($invoiceFields[$key] ?? true) ? 'border-green-200 bg-green-50 hover:bg-green-100' : 'border-gray-200 bg-gray-50 hover:bg-gray-100' }}">
<input type="checkbox" wire:click="toggleField('{{ $key }}')" {{ ($invoiceFields[$key] ?? true) ? 'checked' : '' }}
class="rounded border-gray-300 text-green-600 focus:ring-green-500">
<span class="text-sm {{ ($invoiceFields[$key] ?? true) ? 'text-gray-900' : 'text-gray-400' }}">{{ $label }}</span>
</label>
@endforeach
</div>
</div>
<div>
<h2 class="text-base font-semibold text-gray-900 mb-4">{{ __('إعدادات الفاتورة') }}</h2>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('نص التذييل') }}</label>
<textarea wire:model="invoiceSettings.footer_text" rows="3"
class="w-full rounded-lg border-gray-300 focus:ring-blue-500 text-sm"
placeholder="{{ __('نص يظهر أسفل كل فاتورة') }}"></textarea>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('رمز العملة') }}</label>
<input type="text" wire:model="invoiceSettings.currency_symbol" class="w-full rounded-lg border-gray-300 focus:ring-blue-500" placeholder="ج.م">
</div>
<div class="p-3 bg-blue-50 border border-blue-200 rounded-lg text-xs text-blue-700">
{{ __('الشعار والألوان والخط تُحكم من صفحة الهوية البصرية') }}
<a href="{{ route('settings.branding') }}" wire:navigate class="underline font-medium">{{ __('اضغط هنا') }}</a>
</div>
</div>
</div>
</div> </div>
<div> @endif
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('سياسة الإرجاع') }}</label>
<input type="text" wire:model="settings.return_policy" class="w-full rounded-lg border-gray-300 focus:ring-blue-500" placeholder="لا يمكن استرجاع المبلغ بعد 7 أيام"> {{-- =================== PAYMENT TAB =================== --}}
@if($activeTab === 'payment')
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<div class="lg:col-span-2">
<h2 class="text-base font-semibold text-gray-900 mb-4">{{ __('الحقول المعروضة في إيصال الدفع') }}</h2>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-2">
@foreach($paymentFieldLabels as $key => $label)
<label class="flex items-center gap-3 p-3 rounded-lg border cursor-pointer transition-colors
{{ ($paymentFields[$key] ?? true) ? 'border-green-200 bg-green-50 hover:bg-green-100' : 'border-gray-200 bg-gray-50 hover:bg-gray-100' }}">
<input type="checkbox" wire:click="toggleField('{{ $key }}')" {{ ($paymentFields[$key] ?? true) ? 'checked' : '' }}
class="rounded border-gray-300 text-green-600 focus:ring-green-500">
<span class="text-sm {{ ($paymentFields[$key] ?? true) ? 'text-gray-900' : 'text-gray-400' }}">{{ $label }}</span>
</label>
@endforeach
</div>
</div>
<div>
<h2 class="text-base font-semibold text-gray-900 mb-4">{{ __('إعدادات إيصال الدفع') }}</h2>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('نص التذييل') }}</label>
<textarea wire:model="paymentSettings.footer_text" rows="3"
class="w-full rounded-lg border-gray-300 focus:ring-blue-500 text-sm"
placeholder="{{ __('نص يظهر أسفل كل إيصال') }}"></textarea>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('رمز العملة') }}</label>
<input type="text" wire:model="paymentSettings.currency_symbol" class="w-full rounded-lg border-gray-300 focus:ring-blue-500" placeholder="ج.م">
</div>
</div>
</div>
</div> </div>
@endif
@endif {{-- end selectedBranchId --}}
</div> </div>
</div> </div>
@endif
</div> </div>
...@@ -8,9 +8,20 @@ ...@@ -8,9 +8,20 @@
$branding = app(\App\Domain\Shared\Services\SettingsService::class); $branding = app(\App\Domain\Shared\Services\SettingsService::class);
$brandLogo = $branding->get('branding.logo'); $brandLogo = $branding->get('branding.logo');
$brandPrimary = $branding->get('branding.primary_color', '#1e40af'); $brandPrimary = $branding->get('branding.primary_color', '#1e40af');
$receiptFooter = $branding->get('branding.receipt_footer_text', __('تم إنشاء هذه الفاتورة إلكترونياً ولا تحتاج إلى توقيع'));
$academyName = app()->bound('current_academy') ? app('current_academy')->name_ar : 'الكابتن'; $academyName = app()->bound('current_academy') ? app('current_academy')->name_ar : 'الكابتن';
$branch = \App\Domain\Identity\Models\Branch::where('academy_id', app('current_academy')?->id)->first(); $branch = \App\Domain\Identity\Models\Branch::where('academy_id', app('current_academy')?->id)->first();
// Load invoice template for field visibility
$invoiceTpl = $branch ? \App\Domain\POS\Models\ReceiptTemplate::resolveFor($branch->id, 'invoice') : null;
$f = $invoiceTpl?->visible_fields ?? \App\Domain\POS\Models\ReceiptTemplate::defaultInvoiceFields();
$tplSettings = $invoiceTpl?->settings ?? \App\Domain\POS\Models\ReceiptTemplate::defaultInvoiceSettings();
$receiptFooter = !empty($tplSettings['footer_text'])
? $tplSettings['footer_text']
: $branding->get('branding.receipt_footer_text', 'تم إنشاء هذه الفاتورة إلكترونياً ولا تحتاج إلى توقيع');
$showSignature = $branding->get('branding.show_signature_in_invoice', false);
$signature = $branding->get('branding.signature');
$termsText = $branding->get('branding.terms_and_conditions', '');
$taxNumber = $branding->get('financial.tax_registration_number', '');
@endphp @endphp
<link href="https://fonts.googleapis.com/css2?family=Cairo:wght@400;600;700&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Cairo:wght@400;600;700&display=swap" rel="stylesheet">
<style> <style>
...@@ -151,15 +162,20 @@ ...@@ -151,15 +162,20 @@
<div class="invoice-wrapper"> <div class="invoice-wrapper">
<div class="header"> <div class="header">
<div class="brand"> <div class="brand">
@if($brandLogo) @if(($f['header_logo'] ?? true) && $brandLogo)
<img src="{{ Storage::disk('public')->url($brandLogo) }}" alt="{{ $academyName }}"> <img src="{{ Storage::disk('public')->url($brandLogo) }}" alt="{{ $academyName }}">
@endif @endif
<div> <div>
<h1>{{ __('فاتورة') }}</h1> <h1>{{ __('فاتورة') }}</h1>
@if($f['header_academy_name'] ?? true)
<p style="color: #64748b; margin-top: 2px; font-size: 13px;">{{ $academyName }}</p> <p style="color: #64748b; margin-top: 2px; font-size: 13px;">{{ $academyName }}</p>
@if($branch) @endif
@if(($f['header_branch'] ?? true) && $branch)
<p style="color: #94a3b8; font-size: 11px;">{{ $branch->name_ar }}</p> <p style="color: #94a3b8; font-size: 11px;">{{ $branch->name_ar }}</p>
@endif @endif
@if(($f['header_tax_number'] ?? false) && $taxNumber)
<p style="color: #94a3b8; font-size: 11px;">{{ __('الرقم الضريبي') }}: {{ $taxNumber }}</p>
@endif
</div> </div>
</div> </div>
<div class="meta"> <div class="meta">
...@@ -175,7 +191,9 @@ ...@@ -175,7 +191,9 @@
</div> </div>
</div> </div>
@if(($f['client_details'] ?? true) || ($f['header_branch'] ?? true))
<div class="parties"> <div class="parties">
@if($f['client_details'] ?? true)
<div class="party"> <div class="party">
<h3>{{ __('العميل') }}</h3> <h3>{{ __('العميل') }}</h3>
@if($invoice->billable) @if($invoice->billable)
...@@ -185,6 +203,8 @@ ...@@ -185,6 +203,8 @@
@endif @endif
@endif @endif
</div> </div>
@endif
@if($f['header_branch'] ?? true)
<div class="party"> <div class="party">
<h3>{{ __('من') }}</h3> <h3>{{ __('من') }}</h3>
<p><strong>{{ $academyName }}</strong></p> <p><strong>{{ $academyName }}</strong></p>
...@@ -197,8 +217,11 @@ ...@@ -197,8 +217,11 @@
@endif @endif
@endif @endif
</div> </div>
@endif
</div> </div>
@endif
@if($f['items_table'] ?? true)
<div class="items-table"> <div class="items-table">
<table> <table>
<thead> <thead>
...@@ -225,26 +248,29 @@ ...@@ -225,26 +248,29 @@
</tbody> </tbody>
</table> </table>
</div> </div>
@endif
<div class="totals-section"> <div class="totals-section">
<div class="totals"> <div class="totals">
@if($f['subtotal'] ?? true)
<div class="row"> <div class="row">
<span>{{ __('المجموع الفرعي') }}</span> <span>{{ __('المجموع الفرعي') }}</span>
<span dir="ltr">{{ format_money($invoice->subtotal_amount ?? $invoice->total_amount) }}</span> <span dir="ltr">{{ format_money($invoice->subtotal_amount ?? $invoice->total_amount) }}</span>
</div> </div>
@if($invoice->discount_amount > 0) @endif
@if(($f['discount'] ?? true) && $invoice->discount_amount > 0)
<div class="row"> <div class="row">
<span>{{ __('الخصم') }}</span> <span>{{ __('الخصم') }}</span>
<span dir="ltr" style="color: #dc2626;">-{{ format_money($invoice->discount_amount) }}</span> <span dir="ltr" style="color: #dc2626;">-{{ format_money($invoice->discount_amount) }}</span>
</div> </div>
@endif @endif
@if(($invoice->service_fee_amount ?? 0) > 0) @if(($f['service_fee'] ?? true) && ($invoice->service_fee_amount ?? 0) > 0)
<div class="row"> <div class="row">
<span>{{ __('رسوم الخدمة') }}</span> <span>{{ __('رسوم الخدمة') }}</span>
<span dir="ltr">{{ format_money($invoice->service_fee_amount) }}</span> <span dir="ltr">{{ format_money($invoice->service_fee_amount) }}</span>
</div> </div>
@endif @endif
@if($invoice->tax_amount > 0) @if(($f['tax_amount'] ?? true) && $invoice->tax_amount > 0)
<div class="row"> <div class="row">
<span>{{ __('الضريبة') }}</span> <span>{{ __('الضريبة') }}</span>
<span dir="ltr">{{ format_money($invoice->tax_amount) }}</span> <span dir="ltr">{{ format_money($invoice->tax_amount) }}</span>
...@@ -254,7 +280,7 @@ ...@@ -254,7 +280,7 @@
<span>{{ __('الإجمالي') }}</span> <span>{{ __('الإجمالي') }}</span>
<span dir="ltr">{{ format_money($invoice->total_amount) }}</span> <span dir="ltr">{{ format_money($invoice->total_amount) }}</span>
</div> </div>
@if($invoice->paid_amount > 0) @if(($f['paid_amount'] ?? true) && $invoice->paid_amount > 0)
<div class="row paid"> <div class="row paid">
<span>{{ __('المدفوع') }}</span> <span>{{ __('المدفوع') }}</span>
<span dir="ltr">{{ format_money($invoice->paid_amount) }}</span> <span dir="ltr">{{ format_money($invoice->paid_amount) }}</span>
...@@ -267,7 +293,7 @@ ...@@ -267,7 +293,7 @@
</div> </div>
</div> </div>
@if($invoice->payments && $invoice->payments->count()) @if(($f['payments_history'] ?? true) && $invoice->payments && $invoice->payments->count())
<div class="payments-section"> <div class="payments-section">
<h3>{{ __('المدفوعات') }}</h3> <h3>{{ __('المدفوعات') }}</h3>
<table> <table>
...@@ -293,9 +319,25 @@ ...@@ -293,9 +319,25 @@
</div> </div>
@endif @endif
@if(($f['signature'] ?? false) && $showSignature && $signature)
<div style="padding: 12px 20px; text-align: end;">
<img src="{{ Storage::disk('public')->url($signature) }}" alt="{{ __('التوقيع') }}" style="height: 50px; object-fit: contain;">
<p style="font-size: 11px; color: #94a3b8; margin-top: 4px;">{{ __('التوقيع المعتمد') }}</p>
</div>
@endif
@if(($f['terms_conditions'] ?? false) && $termsText)
<div style="padding: 12px 20px; border-top: 1px solid #e2e8f0; font-size: 11px; color: #64748b;">
<p style="font-weight: 600; margin-bottom: 4px;">{{ __('الشروط والأحكام') }}</p>
<p style="white-space: pre-wrap;">{{ $termsText }}</p>
</div>
@endif
@if($f['footer_text'] ?? true)
<div class="footer"> <div class="footer">
{{ $receiptFooter }} {{ $receiptFooter }}
</div> </div>
@endif
<div class="actions"> <div class="actions">
<button onclick="window.print()" class="btn btn-print"> <button onclick="window.print()" class="btn btn-print">
......
...@@ -9,6 +9,13 @@ ...@@ -9,6 +9,13 @@
$brandLogo = $branding->get('branding.logo'); $brandLogo = $branding->get('branding.logo');
$brandPrimary = $branding->get('branding.primary_color', '#1e40af'); $brandPrimary = $branding->get('branding.primary_color', '#1e40af');
$academyName = app()->bound('current_academy') ? app('current_academy')->name_ar : 'الكابتن'; $academyName = app()->bound('current_academy') ? app('current_academy')->name_ar : 'الكابتن';
$payBranch = \App\Domain\Identity\Models\Branch::where('academy_id', app('current_academy')?->id)->first();
$payTpl = $payBranch ? \App\Domain\POS\Models\ReceiptTemplate::resolveFor($payBranch->id, 'payment') : null;
$pf = $payTpl?->visible_fields ?? \App\Domain\POS\Models\ReceiptTemplate::defaultPaymentFields();
$payTplSettings = $payTpl?->settings ?? \App\Domain\POS\Models\ReceiptTemplate::defaultPaymentSettings();
$payFooter = !empty($payTplSettings['footer_text'])
? $payTplSettings['footer_text']
: 'تم إنشاء هذا المستند إلكترونياً ولا يحتاج إلى توقيع';
@endphp @endphp
<link href="https://fonts.googleapis.com/css2?family=Cairo:wght@400;600;700&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Cairo:wght@400;600;700&display=swap" rel="stylesheet">
<style> <style>
...@@ -114,11 +121,13 @@ ...@@ -114,11 +121,13 @@
<body> <body>
<div class="receipt-wrapper"> <div class="receipt-wrapper">
<div class="header"> <div class="header">
@if($brandLogo) @if(($pf['header_logo'] ?? true) && $brandLogo)
<img src="{{ Storage::disk('public')->url($brandLogo) }}" alt="{{ $academyName }}"> <img src="{{ Storage::disk('public')->url($brandLogo) }}" alt="{{ $academyName }}">
@endif @endif
<h1>{{ __('إيصال دفع') }}</h1> <h1>{{ __('إيصال دفع') }}</h1>
@if($pf['header_academy_name'] ?? true)
<div class="academy">{{ $academyName }}</div> <div class="academy">{{ $academyName }}</div>
@endif
</div> </div>
<div class="amount-section"> <div class="amount-section">
...@@ -126,50 +135,49 @@ ...@@ -126,50 +135,49 @@
<div class="amount-value">{{ format_money($payment->amount) }}</div> <div class="amount-value">{{ format_money($payment->amount) }}</div>
</div> </div>
@php
$methodLabels = ['cash'=>'نقدي','card'=>'بطاقة','bank_transfer'=>'تحويل بنكي','wallet'=>'محفظة','online'=>'إلكتروني','cheque'=>'شيك','other'=>'أخرى'];
$methodValue = $payment->method?->value ?? $payment->method ?? '';
$payerName = $payment->invoice?->contact_name
?? $payment->invoice?->billable?->person?->name_ar
?? $payment->invoice?->billable?->person?->name
?? null;
$statusValue = $payment->status?->value ?? $payment->status ?? 'pending';
$statusLabels = ['pending'=>'معلق','confirmed'=>'مؤكد','failed'=>'فاشل','cancelled'=>'ملغى','refunded'=>'مسترد'];
@endphp
<div class="info-section"> <div class="info-section">
@if($pf['reference_number'] ?? true)
<div class="info-row"> <div class="info-row">
<span class="label">{{ __('رقم المرجع') }}</span> <span class="label">{{ __('رقم المرجع') }}</span>
<span class="value" dir="ltr">{{ $payment->reference ?? 'PAY-' . str_pad($payment->id, 6, '0', STR_PAD_LEFT) }}</span> <span class="value" dir="ltr">{{ $payment->reference ?? 'PAY-' . str_pad($payment->id, 6, '0', STR_PAD_LEFT) }}</span>
</div> </div>
@endif
@if($pf['date'] ?? true)
<div class="info-row"> <div class="info-row">
<span class="label">{{ __('التاريخ') }}</span> <span class="label">{{ __('التاريخ') }}</span>
<span class="value" dir="ltr">{{ $payment->payment_date?->format('Y/m/d') ?? $payment->created_at?->format('Y/m/d') }}</span> <span class="value" dir="ltr">{{ $payment->payment_date?->format('Y/m/d') ?? $payment->created_at?->format('Y/m/d') }}</span>
</div> </div>
@php @endif
$methodLabels = [ @if($pf['payment_method'] ?? true)
'cash' => 'نقدي',
'card' => 'بطاقة',
'bank_transfer' => 'تحويل بنكي',
'wallet' => 'محفظة',
'online' => 'إلكتروني',
'cheque' => 'شيك',
'other' => 'أخرى',
];
$methodValue = $payment->method?->value ?? $payment->method ?? '';
@endphp
<div class="info-row"> <div class="info-row">
<span class="label">{{ __('طريقة الدفع') }}</span> <span class="label">{{ __('طريقة الدفع') }}</span>
<span class="value">{{ $methodLabels[$methodValue] ?? $methodValue }}</span> <span class="value">{{ $methodLabels[$methodValue] ?? $methodValue }}</span>
</div> </div>
@if($payment->invoice) @endif
@if(($pf['invoice_number'] ?? true) && $payment->invoice)
<div class="info-row"> <div class="info-row">
<span class="label">{{ __('رقم الفاتورة') }}</span> <span class="label">{{ __('رقم الفاتورة') }}</span>
<span class="value" dir="ltr">{{ $payment->invoice->number }}</span> <span class="value" dir="ltr">{{ $payment->invoice->number }}</span>
</div> </div>
@endif @endif
@php @if(($pf['payer_name'] ?? true) && $payerName)
$payerName = $payment->invoice?->contact_name
?? $payment->invoice?->billable?->person?->name_ar
?? $payment->invoice?->billable?->person?->name
?? null;
@endphp
@if($payerName)
<div class="info-row"> <div class="info-row">
<span class="label">{{ __('الدافع') }}</span> <span class="label">{{ __('الدافع') }}</span>
<span class="value">{{ $payerName }}</span> <span class="value">{{ $payerName }}</span>
</div> </div>
@endif @endif
@if($payment->creator) @if(($pf['received_by'] ?? true) && $payment->creator)
<div class="info-row"> <div class="info-row">
<span class="label">{{ __('استلم بواسطة') }}</span> <span class="label">{{ __('استلم بواسطة') }}</span>
<span class="value">{{ $payment->creator->name ?? '' }}</span> <span class="value">{{ $payment->creator->name ?? '' }}</span>
...@@ -177,30 +185,24 @@ ...@@ -177,30 +185,24 @@
@endif @endif
</div> </div>
@php @if($pf['status_badge'] ?? true)
$statusValue = $payment->status?->value ?? $payment->status ?? 'pending';
$statusLabels = [
'pending' => 'معلق',
'confirmed' => 'مؤكد',
'failed' => 'فاشل',
'cancelled' => 'ملغى',
'refunded' => 'مسترد',
];
@endphp
<div style="text-align: center; padding: 12px 16px; border-bottom: 1px dashed #e2e8f0;"> <div style="text-align: center; padding: 12px 16px; border-bottom: 1px dashed #e2e8f0;">
<span class="status-badge status-{{ $statusValue }}">{{ $statusLabels[$statusValue] ?? $statusValue }}</span> <span class="status-badge status-{{ $statusValue }}">{{ $statusLabels[$statusValue] ?? $statusValue }}</span>
</div> </div>
@endif
@if($payment->notes) @if(($pf['notes'] ?? true) && $payment->notes)
<div class="info-section"> <div class="info-section">
<div style="font-size: 12px; color: #64748b;">{{ __('ملاحظات') }}:</div> <div style="font-size: 12px; color: #64748b;">{{ __('ملاحظات') }}:</div>
<div style="font-size: 13px; margin-top: 4px;">{{ $payment->notes }}</div> <div style="font-size: 13px; margin-top: 4px;">{{ $payment->notes }}</div>
</div> </div>
@endif @endif
@if($pf['footer_text'] ?? true)
<div class="footer"> <div class="footer">
{{ __('تم إنشاء هذا المستند إلكترونياً ولا يحتاج إلى توقيع') }} {{ $payFooter }}
</div> </div>
@endif
<div class="actions"> <div class="actions">
<button onclick="window.print()" class="btn btn-print"> <button onclick="window.print()" class="btn btn-print">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment