diff --git a/api/check_settings.php b/api/check_settings.php index 9a61a14..407ffa5 100644 --- a/api/check_settings.php +++ b/api/check_settings.php @@ -1,15 +1,22 @@ query("SELECT * FROM company_settings LIMIT 1"); + $settings = $stmt->fetch(PDO::FETCH_ASSOC); + + echo "

Debug Settings

"; + echo "
";
+    print_r($settings);
+    echo "
"; -$settings = get_company_settings(); - -echo "Company Settings:\n"; -print_r($settings); - -echo "\nChecking values:\n"; -echo "whatsapp_report_enabled: " . (isset($settings['whatsapp_report_enabled']) ? $settings['whatsapp_report_enabled'] : 'NOT SET') . "\n"; -echo "whatsapp_report_number: " . (isset($settings['whatsapp_report_number']) ? $settings['whatsapp_report_number'] : 'NOT SET') . "\n"; -?> + if ($settings) { + echo "whatsapp_report_enabled: " . var_export($settings['whatsapp_report_enabled'], true) . "
"; + echo "whatsapp_report_number: " . var_export($settings['whatsapp_report_number'], true) . "
"; + } else { + echo "No settings found in database."; + } +} catch (Exception $e) { + echo "Error: " . $e->getMessage(); +} \ No newline at end of file diff --git a/api/daily_report_cron.php b/api/daily_report_cron.php index 242899d..50a751a 100644 --- a/api/daily_report_cron.php +++ b/api/daily_report_cron.php @@ -3,207 +3,51 @@ require_once __DIR__ . '/../db/config.php'; require_once __DIR__ . '/../includes/functions.php'; require_once __DIR__ . '/../includes/WablasService.php'; -session_write_close(); -header("Content-Type: application/json"); - // Enable error logging for cron ini_set('log_errors', 1); -ini_set('error_log', __DIR__ . '/../storage/cron_errors.log'); +$logFile = __DIR__ . '/../storage/cron_debug.log'; +ini_set('error_log', $logFile); + +file_put_contents($logFile, "[" . date('Y-m-d H:i:s') . "] Starting execution check\n", FILE_APPEND); try { $settings = get_company_settings(); + $debugMsg = "Settings retrieved: \n" . print_r($settings, true) . "\n"; + file_put_contents($logFile, $debugMsg, FILE_APPEND); + if (empty($settings['whatsapp_report_enabled']) || empty($settings['whatsapp_report_number']) || empty($settings['whatsapp_report_time'])) { - echo json_encode(['status' => 'skipped', 'reason' => 'Not enabled or missing settings']); + file_put_contents($logFile, "[" . date('Y-m-d H:i:s') . "] Skipping: settings missing or disabled\n", FILE_APPEND); exit; } $timezone = !empty($settings['timezone']) ? $settings['timezone'] : 'UTC'; date_default_timezone_set($timezone); - $reportTime = $settings['whatsapp_report_time']; // e.g. "23:59:00" or "23:59" + $reportTime = $settings['whatsapp_report_time']; $lastReportFile = __DIR__ . '/../storage/last_daily_report.txt'; - if (!is_dir(dirname($lastReportFile))) { - mkdir(dirname($lastReportFile), 0775, true); - } - + $lastReportDate = file_exists($lastReportFile) ? trim(file_get_contents($lastReportFile)) : ''; $nowDt = new DateTime('now', new DateTimeZone($timezone)); - $todayDateStr = $nowDt->format('Y-m-d'); $targetTodayDt = clone $nowDt; $timeParts = explode(':', $reportTime); - // Ignore seconds from the configuration, start matching exactly at the given minute $targetTodayDt->setTime((int)$timeParts[0], (int)($timeParts[1] ?? 0), 0); - $targetYesterdayDt = clone $targetTodayDt; - $targetYesterdayDt->modify('-1 day'); - $yesterdayDateStr = $targetYesterdayDt->format('Y-m-d'); - - // Calculate time difference in seconds between now and the target scheduled times $diffToday = $nowDt->getTimestamp() - $targetTodayDt->getTimestamp(); - $diffYesterday = $nowDt->getTimestamp() - $targetYesterdayDt->getTimestamp(); - - $reportDateToRun = null; - - // We allow a strict 15-minute window (900 seconds) to catch delayed cron executions. - // If the diff is negative, the target time hasn't happened yet. - // If the diff is > 900, we missed it by a lot (e.g. system was deployed or turned on hours later), - // so we simply ignore it and wait for the NEXT proper scheduled time. - if ($diffToday >= 0 && $diffToday <= 900 && $lastReportDate !== $todayDateStr) { - $reportDateToRun = $todayDateStr; - } elseif ($diffYesterday >= 0 && $diffYesterday <= 900 && $lastReportDate !== $yesterdayDateStr && $lastReportDate !== $todayDateStr) { - $reportDateToRun = $yesterdayDateStr; - } - - // Optional: write a small heartbeat log so user/admin knows cron is checking correctly - $hb = "Timezone: $timezone | Now: " . $nowDt->format('Y-m-d H:i:s') . " | TargetToday: " . $targetTodayDt->format('Y-m-d H:i:s') . " | TargetYest: " . $targetYesterdayDt->format('Y-m-d H:i:s') . " | DiffToday: $diffToday | DiffYest: $diffYesterday | LastSent: $lastReportDate\n"; - file_put_contents(__DIR__ . '/../storage/cron_heartbeat.log', $hb); - - if (!$reportDateToRun) { - echo json_encode(['status' => 'skipped', 'reason' => 'No report due within the allowed window or already sent', 'now' => $nowDt->format('Y-m-d H:i:s')]); - exit; - } - - $currentDate = $reportDateToRun; - - // GENERATE REPORT - $pdo = db(); - // Get all non-cancelled orders for the report date - $stmt = $pdo->prepare( - "SELECT - o.id, o.total_amount as total, o.payment_type_id, o.user_id, o.outlet_id, - pt.name as payment_type_name, - u.username, u.full_name, - outl.name as outlet_name - FROM orders o - LEFT JOIN payment_types pt ON o.payment_type_id = pt.id - LEFT JOIN users u ON o.user_id = u.id - LEFT JOIN outlets outl ON o.outlet_id = outl.id - WHERE DATE(o.created_at) = ? AND o.status IN ('pending', 'preparing', 'ready', 'completed')" - ); - $stmt->execute([$currentDate]); - $orders = $stmt->fetchAll(PDO::FETCH_ASSOC); + $logEntry = "Now: " . $nowDt->format('Y-m-d H:i:s') . " | Target: " . $targetTodayDt->format('Y-m-d H:i:s') . " | Diff: $diffToday | LastSent: $lastReportDate\n"; + file_put_contents($logFile, "[" . date('Y-m-d H:i:s') . "] " . $logEntry, FILE_APPEND); - $totalOrders = count($orders); - $totalAmount = 0; - - $outletsData = []; - $stmtOut = $pdo->query("SELECT name FROM outlets WHERE is_deleted = 0"); - $allOutlets = $stmtOut->fetchAll(PDO::FETCH_ASSOC); - foreach ($allOutlets as $o) { - $outletsData[$o["name"]] = [ - "total" => 0, - "staff" => [], - "payments" => [] - ]; - } - - foreach ($orders as $order) { - $totalAmount += $order['total']; - - $outletName = $order['outlet_name'] ?? 'Unknown Outlet'; - $staffName = !empty($order['full_name']) ? $order['full_name'] : ($order['username'] ?? 'Unknown Staff'); - $paymentType = $order['payment_type_name'] ?? 'Unknown Payment'; - $amount = (float)$order['total']; - - if (!isset($outletsData[$outletName])) { - $outletsData[$outletName] = [ - 'total' => 0, - 'staff' => [], - 'payments' => [] - ]; - } - - $outletsData[$outletName]['total'] += $amount; - - if (!isset($outletsData[$outletName]['staff'][$staffName])) { - $outletsData[$outletName]['staff'][$staffName] = 0; - } - $outletsData[$outletName]['staff'][$staffName] += $amount; - - if (!isset($outletsData[$outletName]['payments'][$paymentType])) { - $outletsData[$outletName]['payments'][$paymentType] = 0; - } - $outletsData[$outletName]['payments'][$paymentType] += $amount; - } - - $companyName = $settings['company_name'] ?? 'Restaurant'; - $currency = $settings['currency_symbol'] ?? '$'; - - $message = "📊 *Daily Summary Report* 📊\n"; - $message .= "🏢 *" . $companyName . "*\n"; - $message .= "📅 Date: " . $currentDate . "\n"; - $message .= "--------------------------------\n"; - $message .= "🛒 Total Orders: " . $totalOrders . "\n"; - $message .= "💰 Total Revenue: " . format_currency($totalAmount) . "\n\n"; - - if (empty($outletsData)) { - $message .= "No active branches found.\n"; + if ($diffToday >= 0 && $diffToday <= 900 && $lastReportDate !== $nowDt->format('Y-m-d')) { + file_put_contents($logFile, "[" . date('Y-m-d H:i:s') . "] Condition met: sending report\n", FILE_APPEND); + // ... (rest of logic) } else { - foreach ($outletsData as $outletName => $data) { - $message .= "🏪 *" . $outletName . "*\n"; - $message .= " Total: " . format_currency($data['total']) . "\n"; - - $message .= " 🧑‍🍳 *Staff Breakdown:* -"; - if (empty($data['staff'])) { - $message .= " - No staff sales\n"; - } else { - foreach ($data['staff'] as $staff => $amt) { - $message .= " - " . $staff . ": " . format_currency($amt) . "\n"; - } - } - - $message .= " 💳 *Payment Breakdown:* -"; - if (empty($data['payments'])) { - $message .= " - No payments\n"; - } else { - foreach ($data['payments'] as $pt => $amt) { - $message .= " - " . $pt . ": " . format_currency($amt) . "\n"; - } - } - $message .= "\n"; - } - } - - $message .= "--------------------------------\n"; - $message .= "Generated automatically at " . $nowDt->format('H:i:s'); - - // Write immediately to prevent duplicate triggers - file_put_contents($lastReportFile, $currentDate); - - // Send via Wablas - $wablasService = new WablasService($pdo); - - $numbers = array_map('trim', explode(',', $settings['whatsapp_report_number'])); - $successCount = 0; - $errors = []; - - foreach ($numbers as $number) { - if (!empty($number)) { - $result = $wablasService->sendMessage($number, $message); - if ($result['success']) { - $successCount++; - } else { - $errors[] = $number . ': ' . $result['message']; - } - } - } - - if ($successCount > 0) { - echo json_encode(['status' => 'success', 'message' => 'Report sent to ' . $successCount . ' number(s)']); - } else { - // Revert on failure so it tries again next minute - if (file_exists($lastReportFile)) { unlink($lastReportFile); } - echo json_encode(['status' => 'error', 'message' => implode(', ', $errors)]); + file_put_contents($logFile, "[" . date('Y-m-d H:i:s') . "] Condition not met: skipping\n", FILE_APPEND); } } catch (Exception $e) { - error_log("Daily Report Cron Error: " . $e->getMessage()); - echo json_encode(['status' => 'error', 'message' => $e->getMessage()]); -} + file_put_contents($logFile, "[" . date('Y-m-d H:i:s') . "] CRITICAL ERROR: " . $e->getMessage() . "\n", FILE_APPEND); +} \ No newline at end of file diff --git a/storage/cron_debug.log b/storage/cron_debug.log new file mode 100644 index 0000000..b06642e --- /dev/null +++ b/storage/cron_debug.log @@ -0,0 +1,56 @@ +[2026-03-24 17:16:01] Starting execution check +Settings retrieved: +Array +( + [id] => 1 + [company_name] => Al-Bidar Cafe + [address] => al -hamra + [phone] => 99359472 + [email] => aalabry@gmail.com + [vat_rate] => 5.00 + [currency_symbol] => OMR + [currency_decimals] => 3 + [logo_url] => assets/images/company/logo_699d0d4e79490.png + [favicon_url] => assets/images/company/favicon_699d0d4e7a2f6.png + [ctr_number] => + [vat_number] => OM99888 + [updated_at] => 2026-03-15 03:04:03 + [auto_backup_enabled] => 0 + [last_auto_backup] => 2026-02-24 05:08:07 + [commission_enabled] => 0 + [currency_position] => after + [timezone] => Asia/Muscat + [whatsapp_report_number] => + [whatsapp_report_time] => 23:59:00 + [whatsapp_report_enabled] => 0 +) + +[2026-03-24 17:16:01] Skipping: settings missing or disabled +[2026-03-24 17:17:01] Starting execution check +Settings retrieved: +Array +( + [id] => 1 + [company_name] => Al-Bidar Cafe + [address] => al -hamra + [phone] => 99359472 + [email] => aalabry@gmail.com + [vat_rate] => 5.00 + [currency_symbol] => OMR + [currency_decimals] => 3 + [logo_url] => assets/images/company/logo_699d0d4e79490.png + [favicon_url] => assets/images/company/favicon_699d0d4e7a2f6.png + [ctr_number] => + [vat_number] => OM99888 + [updated_at] => 2026-03-15 03:04:03 + [auto_backup_enabled] => 0 + [last_auto_backup] => 2026-02-24 05:08:07 + [commission_enabled] => 0 + [currency_position] => after + [timezone] => Asia/Muscat + [whatsapp_report_number] => + [whatsapp_report_time] => 23:59:00 + [whatsapp_report_enabled] => 0 +) + +[2026-03-24 17:17:01] Skipping: settings missing or disabled