exec("SET time_zone = '" . date('P') . "'"); } catch (Exception $e) { cron_log("Warning: Could not set MySQL timezone: " . $e->getMessage()); } $reportTime = $settings['whatsapp_report_time']; $lastReportFile = __DIR__ . '/../storage/last_daily_report.txt'; $lastReportDate = file_exists($lastReportFile) ? trim(file_get_contents($lastReportFile)) : ''; $nowDt = new DateTime('now', new DateTimeZone($timezone)); // Target time for today $targetTodayDt = clone $nowDt; $timeParts = explode(':', $reportTime); $targetTodayDt->setTime((int)$timeParts[0], (int)($timeParts[1] ?? 0), 0); $diffToday = $nowDt->getTimestamp() - $targetTodayDt->getTimestamp(); // Check if within 15 minutes (900 seconds) after the target time AND not sent today if ($diffToday >= 0 && $diffToday <= 900 && $lastReportDate !== $nowDt->format('Y-m-d')) { cron_log("Condition met: sending daily report for " . $nowDt->format('Y-m-d')); $today = $nowDt->format('Y-m-d'); $companyName = $settings['company_name'] ?? 'Company'; // --- 1. Global Stats --- // Total Revenue Today (Confirmed Orders) // Note: Using status != 'cancelled' to include completed, ready, etc. $stmt = $pdo->prepare("SELECT SUM(total_amount) FROM orders WHERE DATE(created_at) = ? AND status != 'cancelled'"); $stmt->execute([$today]); $totalRevenue = $stmt->fetchColumn() ?: 0; // Total Orders Today $stmt = $pdo->prepare("SELECT COUNT(*) FROM orders WHERE DATE(created_at) = ? AND status != 'cancelled'"); $stmt->execute([$today]); $totalOrders = $stmt->fetchColumn() ?: 0; // --- 2. Build Message Header --- $message = "šŸ“Š *Daily Summary Report* šŸ“Š\n"; $message .= "šŸ¢ *" . $companyName . "*\n"; $message .= "šŸ“… Date: " . $today . "\n"; $message .= "--------------------------------\n"; $message .= "šŸ›’ *Total Orders:* " . $totalOrders . "\n"; $message .= "šŸ’° *Total Revenue:* " . format_currency_custom($totalRevenue, $settings) . "\n"; // --- 3. Per-Outlet Stats --- // Get all active outlets $stmtOutlets = $pdo->query("SELECT id, name FROM outlets WHERE is_deleted = 0 ORDER BY id ASC"); $outlets = $stmtOutlets->fetchAll(); foreach ($outlets as $outlet) { $outletId = $outlet['id']; $outletName = $outlet['name']; // Outlet Revenue $stmtRev = $pdo->prepare("SELECT SUM(total_amount) FROM orders WHERE outlet_id = ? AND DATE(created_at) = ? AND status != 'cancelled'"); $stmtRev->execute([$outletId, $today]); $outletRevenue = $stmtRev->fetchColumn() ?: 0; $message .= "\nšŸŖ *" . $outletName . " Total:* " . format_currency_custom($outletRevenue, $settings) . "\n"; // Staff Breakdown for this Outlet $message .= "šŸ§‘ā€šŸ³ *Staff Breakdown:* "; $stmtStaff = $pdo->prepare(" SELECT u.username, u.full_name, COUNT(o.id) as order_count, SUM(o.total_amount) as revenue FROM orders o LEFT JOIN users u ON o.user_id = u.id WHERE o.outlet_id = ? AND DATE(o.created_at) = ? AND o.status != 'cancelled' GROUP BY o.user_id "); $stmtStaff->execute([$outletId, $today]); $staffStats = $stmtStaff->fetchAll(); if (empty($staffStats)) { $message .= "- No staff sales\n"; } else { foreach ($staffStats as $stat) { $staffName = !empty($stat['full_name']) ? $stat['full_name'] : ($stat['username'] ?? 'Unknown'); $message .= "- " . $staffName . ": " . format_currency_custom($stat['revenue'], $settings) . " (" . $stat['order_count'] . " orders)\n"; } } // Payment Breakdown for this Outlet $message .= "šŸ’³ *Payment Breakdown:* "; $stmtPayment = $pdo->prepare(" SELECT pt.name, SUM(o.total_amount) as revenue FROM orders o LEFT JOIN payment_types pt ON o.payment_type_id = pt.id WHERE o.outlet_id = ? AND DATE(o.created_at) = ? AND o.status != 'cancelled' GROUP BY o.payment_type_id "); $stmtPayment->execute([$outletId, $today]); $paymentStats = $stmtPayment->fetchAll(); if (empty($paymentStats)) { $message .= "- No payments\n"; } else { foreach ($paymentStats as $stat) { $paymentName = $stat['name'] ?? 'Unknown'; $message .= "- " . $paymentName . ": " . format_currency_custom($stat['revenue'], $settings) . "\n"; } } } $message .= "--------------------------------\n"; $message .= "Generated automatically at " . $nowDt->format('H:i:s'); // --- 4. Send Message --- $wablas = new WablasService($pdo); $recipients = explode(',', $settings['whatsapp_report_number']); $anySuccess = false; foreach ($recipients as $recipient) { $recipient = trim($recipient); if (empty($recipient)) continue; cron_log("Sending detailed report to: " . $recipient); $result = $wablas->sendMessage($recipient, $message); if (!empty($result['success']) && $result['success'] == true) { cron_log("Report sent successfully to " . $recipient); $anySuccess = true; } else { cron_log("Failed to send report to " . $recipient . ": " . ($result['message'] ?? 'Unknown error')); } } if ($anySuccess) { file_put_contents($lastReportFile, $today); } } } catch (Exception $e) { cron_log("CRITICAL ERROR: " . $e->getMessage()); }