Update: 2026-05-08 14:29:22
This commit is contained in:
@@ -33,7 +33,7 @@ class NotificationService
|
|||||||
$stmt = $db->prepare("SELECT push_token FROM user_devices WHERE user_id = ? AND device_fingerprint = ? AND push_token IS NOT NULL");
|
$stmt = $db->prepare("SELECT push_token FROM user_devices WHERE user_id = ? AND device_fingerprint = ? AND push_token IS NOT NULL");
|
||||||
$stmt->execute([$userId, $deviceId]);
|
$stmt->execute([$userId, $deviceId]);
|
||||||
} else {
|
} else {
|
||||||
$stmt = $db->prepare("SELECT push_token FROM user_devices WHERE user_id = ? AND push_token IS NOT NULL AND is_active = 1");
|
$stmt = $db->prepare("SELECT push_token FROM user_devices WHERE user_id = ? AND push_token IS NOT NULL");
|
||||||
$stmt->execute([$userId]);
|
$stmt->execute([$userId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ class NotificationService
|
|||||||
$stmt = $db->prepare("SELECT push_token FROM user_devices WHERE user_id = ? AND device_fingerprint = ? AND push_token IS NOT NULL");
|
$stmt = $db->prepare("SELECT push_token FROM user_devices WHERE user_id = ? AND device_fingerprint = ? AND push_token IS NOT NULL");
|
||||||
$stmt->execute([$userId, $deviceId]);
|
$stmt->execute([$userId, $deviceId]);
|
||||||
} else {
|
} else {
|
||||||
$stmt = $db->prepare("SELECT push_token FROM user_devices WHERE user_id = ? AND push_token IS NOT NULL AND is_active = 1");
|
$stmt = $db->prepare("SELECT push_token FROM user_devices WHERE user_id = ? AND push_token IS NOT NULL");
|
||||||
$stmt->execute([$userId]);
|
$stmt->execute([$userId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,6 +130,31 @@ class NotificationService
|
|||||||
],
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
} else {
|
||||||
|
// Silent push / Live Activity Update
|
||||||
|
$message['android'] = [
|
||||||
|
'priority' => 'high'
|
||||||
|
];
|
||||||
|
$message['apns'] = [
|
||||||
|
'headers' => [
|
||||||
|
'apns-priority' => '5',
|
||||||
|
'apns-push-type' => 'background'
|
||||||
|
],
|
||||||
|
'payload' => [
|
||||||
|
'aps' => [
|
||||||
|
'content-available' => 1
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
// If the data contains live activity update markers, adjust headers for iOS ActivityKit
|
||||||
|
if (isset($data['type']) && $data['type'] === 'batch_progress') {
|
||||||
|
$message['apns']['headers']['apns-push-type'] = 'liveactivity';
|
||||||
|
$message['apns']['headers']['apns-priority'] = '10';
|
||||||
|
$message['apns']['payload']['aps']['content-state'] = $data;
|
||||||
|
$message['apns']['payload']['aps']['timestamp'] = time();
|
||||||
|
$message['apns']['payload']['aps']['event'] = 'update';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$payload = ['message' => $message];
|
$payload = ['message' => $message];
|
||||||
|
|||||||
@@ -126,6 +126,9 @@ try {
|
|||||||
// Update batch progress
|
// Update batch progress
|
||||||
$db->prepare("UPDATE invoice_batches SET processed_images = processed_images + 1 WHERE id = ?")->execute([$batchId]);
|
$db->prepare("UPDATE invoice_batches SET processed_images = processed_images + 1 WHERE id = ?")->execute([$batchId]);
|
||||||
|
|
||||||
|
// Increment Quota
|
||||||
|
QuotaMiddleware::incrementInvoiceUsage($tenantId);
|
||||||
|
|
||||||
$db->commit();
|
$db->commit();
|
||||||
echo "Success: Created Invoice $invoiceId\n";
|
echo "Success: Created Invoice $invoiceId\n";
|
||||||
|
|
||||||
@@ -143,14 +146,17 @@ try {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Increment Quota
|
} catch (\Exception $pushErr) {
|
||||||
QuotaMiddleware::incrementInvoiceUsage($tenantId);
|
echo "Push error: " . $pushErr->getMessage() . "\n";
|
||||||
|
}
|
||||||
|
} catch (\Exception $e) {
|
||||||
} catch (Exception $e) {
|
if ($db->inTransaction()) {
|
||||||
$db->rollBack();
|
$db->rollBack();
|
||||||
|
}
|
||||||
echo "DB Error: " . $e->getMessage() . "\n";
|
echo "DB Error: " . $e->getMessage() . "\n";
|
||||||
$db->prepare("UPDATE invoice_processing_queue SET status = 'failed', error_message = ? WHERE id = ?")->execute([$e->getMessage(), $queueId]);
|
try {
|
||||||
|
$db->prepare("UPDATE invoice_processing_queue SET status = 'failed', error_message = ? WHERE id = ?")->execute([$e->getMessage(), $queueId]);
|
||||||
|
} catch (\Exception $e2) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if batch is complete
|
// Check if batch is complete
|
||||||
|
|||||||
@@ -57,6 +57,12 @@ $stmt = $db->prepare("
|
|||||||
");
|
");
|
||||||
$stmt->execute([$batchId]);
|
$stmt->execute([$batchId]);
|
||||||
|
|
||||||
|
// 3. If it's a single invoice, try triggering the worker in the background immediately
|
||||||
|
// This helps if the Cron Job is delayed or failing.
|
||||||
|
$workerPath = ROOT_PATH . '/app/cron/process_batches.php';
|
||||||
|
$logPath = STORAGE_PATH . '/logs/cron.log';
|
||||||
|
exec("php " . escapeshellarg($workerPath) . " >> " . escapeshellarg($logPath) . " 2>&1 &");
|
||||||
|
|
||||||
json_success([
|
json_success([
|
||||||
'batch_id' => $batchId,
|
'batch_id' => $batchId,
|
||||||
'status' => 'processing',
|
'status' => 'processing',
|
||||||
|
|||||||
@@ -447,7 +447,8 @@ class DashboardView extends GetView<DashboardController> {
|
|||||||
InkWell(
|
InkWell(
|
||||||
onTap: () => _showBadgesDialog(gamification),
|
onTap: () => _showBadgesDialog(gamification),
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
padding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white24,
|
color: Colors.white24,
|
||||||
borderRadius: BorderRadius.circular(20),
|
borderRadius: BorderRadius.circular(20),
|
||||||
@@ -457,11 +458,13 @@ class DashboardView extends GetView<DashboardController> {
|
|||||||
children: [
|
children: [
|
||||||
const Text(
|
const Text(
|
||||||
'المكافآت ',
|
'المكافآت ',
|
||||||
style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
|
style: TextStyle(
|
||||||
|
color: Colors.white, fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
'$badgesCount/$availableBadges',
|
'$badgesCount/$availableBadges',
|
||||||
style: const TextStyle(color: Colors.white70, fontSize: 12),
|
style: const TextStyle(
|
||||||
|
color: Colors.white70, fontSize: 12),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -494,20 +497,26 @@ class DashboardView extends GetView<DashboardController> {
|
|||||||
|
|
||||||
Get.dialog(
|
Get.dialog(
|
||||||
AlertDialog(
|
AlertDialog(
|
||||||
title: const Text('شاراتك ومكافآتك', textAlign: TextAlign.center, style: TextStyle(color: Color(0xFF0F4C81))),
|
title: const Text('شاراتك ومكافآتك',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(color: Color(0xFF0F4C81))),
|
||||||
content: SizedBox(
|
content: SizedBox(
|
||||||
width: double.maxFinite,
|
width: double.maxFinite,
|
||||||
child: badges.isEmpty
|
child: badges.isEmpty
|
||||||
? const Text('لم تحصل على أي شارات بعد. قم برفع الفواتير لتبدأ!', textAlign: TextAlign.center)
|
? const Text('لم تحصل على أي شارات بعد. قم برفع الفواتير لتبدأ!',
|
||||||
|
textAlign: TextAlign.center)
|
||||||
: ListView.builder(
|
: ListView.builder(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
itemCount: badges.length,
|
itemCount: badges.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final b = badges[index];
|
final b = badges[index];
|
||||||
return ListTile(
|
return ListTile(
|
||||||
leading: Text(b['badge_icon'] ?? '🌟', style: const TextStyle(fontSize: 24)),
|
leading: Text(b['badge_icon'] ?? '🌟',
|
||||||
title: Text(b['badge_name'] ?? '', style: const TextStyle(fontWeight: FontWeight.bold)),
|
style: const TextStyle(fontSize: 24)),
|
||||||
subtitle: Text('تم الحصول عليها: ${(b['earned_at'] ?? '').toString().split(' ')[0]}'),
|
title: Text(b['badge_name'] ?? '',
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.bold)),
|
||||||
|
subtitle: Text(
|
||||||
|
'تم الحصول عليها: ${(b['earned_at'] ?? '').toString().split(' ')[0]}'),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user