+
+
+ 📄
-
-
الخصم الإجمالي
-
+
إجمالي الفواتير
+
+
-
- ضريبة المبيعات
-
+
+
+
+
+ ⏳
-
-
الإجمالي النهائي
-
+
قيد المعالجة
+
+
+
+
+
+
+ ✅
+
+
تم الاعتماد
+
+
-
-
-
-
-
-
![QR Code]()
-
-
-
-
الرقم الموحد:
-
تاريخ الرفع:
-
-
+
+
+
+
+ ⚡ إجراءات سريعة
+
+
+
+
+
+
-
+
-
-
-
-
-
+
+
+
+
+
+
+ | الشركة |
+ الأرقام الرسمية |
+ العنوان |
+ المكتب |
+ إجراءات |
+
+
+
+
+
+
+ 🏢
+ لا توجد شركات مسجلة بعد
+
+ |
+
+
+
+ |
+
+ |
+
+ TIN:
+ CRN:
+ |
+ |
+ |
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+ | المستخدم |
+ المكتب |
+ الدور |
+ الحالة |
+ إجراءات |
+
+
+
+
+
+
+ 👥
+ لا يوجد مستخدمون بعد
+
+ |
+
+
+
+ |
+
+
+ |
+ |
+
+
+ |
+
+
+
+
+
+ |
+
+
+ |
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ✨
+ تفاصيل الفاتورة المستخرجة
+
+
+
+ AI-Powered Extraction (Gemini 1.5 Flash)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ✨ تم الاعتماد محلياً
+
+ في انتظار المزامنة مع جوفوترة
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 📤
+
+
رفع فواتير جديدة
+
سيقوم النظام باستخراج البيانات آلياً باستخدام الذكاء الاصطناعي المتقدم
+
+
+
+
+
+
+
+
+
+
+
+ 👥
+
+
إضافة مستخدم جديد
+
+
+
@@ -442,7 +870,6 @@
showAddTenantModal: false,
showUploadModal: false,
showViewModal: false,
- showCompanyStatsModal: false,
isUploading: false,
isApproving: false,
globalError: '',
@@ -451,11 +878,21 @@
uploadData: { company_id: '' },
selectedFile: null,
currentInvoice: null,
- companyStats: null,
init() {
if (!this.user) { window.location.href = '/login.php'; return; }
this.loadAll();
+
+ // Confetti celebration on successful actions (optional enhancement)
+ if (sessionStorage.getItem('celebrate')) {
+ confetti({
+ particleCount: 100,
+ spread: 70,
+ origin: { y: 0.6 },
+ colors: ['#10b981', '#06b6d4', '#8b5cf6']
+ });
+ sessionStorage.removeItem('celebrate');
+ }
},
setPage(p) {
@@ -463,10 +900,13 @@
this.loadAll();
},
- title() { return { dashboard: 'نظرة عامة', users: 'إدارة المستخدمين', companies: 'الشركات', invoices: 'الفواتير' }[this.page] || ''; },
- subtitle() { return { dashboard: 'تحليلات المنصة', users: 'إدارة أدوار الوصول', invoices: 'إدارة الفواتير المرفوعة' }[this.page] || ''; },
+ title() { return { dashboard: 'نظرة عامة', users: 'إدارة المستخدمين', companies: 'الشركات', invoices: 'الفواتير', tenants: 'المكاتب المحاسبية' }[this.page] || ''; },
+ subtitle() { return { dashboard: 'تحليلات المنصة الذكية', users: 'إدارة أدوار الوصول والصلاحيات', companies: 'إدارة بيانات الشركات المسجلة', invoices: 'إدارة ومعالجة الفواتير المرفوعة', tenants: 'إدارة المكاتب المحاسبية الشريكة' }[this.page] || ''; },
- showError(msg) { this.globalError = msg; setTimeout(() => this.globalError = '', 6000); },
+ showError(msg) {
+ this.globalError = msg;
+ setTimeout(() => this.globalError = '', 6000);
+ },
token() { return localStorage.getItem('access_token'); },
async apiRequest(route, method = 'GET', body = null) {
@@ -479,24 +919,20 @@
};
if (body) options.body = JSON.stringify(body);
- try {
- const res = await fetch('/index.php?route=' + route, options);
-
- if (res.status === 401) {
- const json = await res.json();
- if (json.code === 'TOKEN_EXPIRED') {
- localStorage.clear();
- window.location.href = '/login.php';
- return null;
- }
- }
-
+ const res = await fetch('/index.php?route=' + route, options);
+
+ // Session Expired Check
+ if (res.status === 401) {
const json = await res.json();
- return json.success ? json.data : (this.showError(json.message), null);
- } catch (e) {
- this.showError('فشل الاتصال بالخادم');
- return null;
+ if (json.code === 'TOKEN_EXPIRED') {
+ localStorage.clear();
+ window.location.href = '/login.php';
+ return null;
+ }
}
+
+ const json = await res.json();
+ return json.success ? json.data : (this.showError(json.message), null);
},
async apiGet(route) { return this.apiRequest(route); },
@@ -515,14 +951,6 @@
async loadStats() { this.stats = await this.apiGet('v1/dashboard/stats') || {}; },
async loadTenants() { this.tenants = await this.apiGet('v1/tenants') || []; },
- async showCompanyStats(id) {
- const data = await this.apiGet('v1/companies/stats&id=' + id);
- if (data) {
- this.companyStats = data;
- this.showCompanyStatsModal = true;
- }
- },
-
async viewInvoice(id) {
const data = await this.apiGet('v1/invoices/view&id=' + id);
if (data) {
@@ -532,15 +960,23 @@
},
async approveInvoice(id) {
- if (!confirm('هل أنت متأكد من اعتماد الفاتورة؟')) return;
+ if (!confirm('هل أنت متأكد من اعتماد الفاتورة وإرسالها إلى جوفوترة؟')) return;
this.isApproving = true;
try {
const data = await this.apiRequest('v1/invoices/approve', 'POST', { id: id });
if (data) {
- alert(data.message || '✅ تم الاعتماد بنجاح!');
+ // Trigger celebration
+ confetti({
+ particleCount: 150,
+ spread: 100,
+ origin: { y: 0.7 },
+ colors: ['#10b981', '#06b6d4']
+ });
+ sessionStorage.setItem('celebrate', 'true');
+
+ alert('✅ تم الاعتماد بنجاح!');
this.viewInvoice(id);
this.loadInvoices();
- this.loadStats();
}
} catch (e) {
this.showError('خطأ غير متوقع: ' + e.message);
@@ -551,16 +987,12 @@
generateQRPng(base64Tlv) {
if (!base64Tlv) return '';
- try {
- const qr = new QRious({
- value: base64Tlv,
- size: 200,
- level: 'M'
- });
- return qr.toDataURL().split(',')[1];
- } catch (e) {
- return '';
- }
+ const qr = new QRious({
+ value: base64Tlv,
+ size: 200,
+ level: 'M'
+ });
+ return qr.toDataURL().split(',')[1];
},
handleFile(e) { this.selectedFile = e.target.files[0]; },
@@ -572,24 +1004,19 @@
formData.append('company_id', this.uploadData.company_id);
formData.append('invoice', this.selectedFile);
- try {
- const res = await fetch('/index.php?route=v1/invoices/upload', {
- method: 'POST',
- headers: { 'Authorization': 'Bearer ' + this.token() },
- body: formData
- });
- const json = await res.json();
- this.isUploading = false;
- if (json.success) {
- this.showUploadModal = false;
- this.loadInvoices();
- this.viewInvoice(json.data.id);
- } else {
- this.showError(json.message);
- }
- } catch (e) {
- this.isUploading = false;
- this.showError('فشل رفع الملف');
+ const res = await fetch('/index.php?route=v1/invoices/upload', {
+ method: 'POST',
+ headers: { 'Authorization': 'Bearer ' + this.token() },
+ body: formData
+ });
+ const json = await res.json();
+ this.isUploading = false;
+ if (json.success) {
+ this.showUploadModal = false;
+ this.loadInvoices();
+ this.viewInvoice(json.data.id);
+ } else {
+ this.showError(json.message);
}
},
@@ -598,4 +1025,4 @@
});
-
+
\ No newline at end of file