update 0 summery result
This commit is contained in:
parent
07fa5eff07
commit
241682d60b
@ -14,24 +14,41 @@ function cron_log($msg) {
|
|||||||
file_put_contents($logFile, "[" . date('Y-m-d H:i:s') . "] " . $msg . "\n", FILE_APPEND);
|
file_put_contents($logFile, "[" . date('Y-m-d H:i:s') . "] " . $msg . "\n", FILE_APPEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper to format currency
|
||||||
|
function format_currency_custom($amount, $settings) {
|
||||||
|
$symbol = $settings['currency_symbol'] ?? '$';
|
||||||
|
$decimals = (int)($settings['currency_decimals'] ?? 3); // Default to 3 decimals as per user example (0.000 OMR)
|
||||||
|
$position = $settings['currency_position'] ?? 'after'; // Default to after as per user example (0.000 OMR)
|
||||||
|
|
||||||
|
$formatted = number_format((float)$amount, $decimals);
|
||||||
|
return ($position === 'after') ? "$formatted $symbol" : "$symbol $formatted";
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$settings = get_company_settings();
|
$settings = get_company_settings();
|
||||||
|
|
||||||
if (empty($settings['whatsapp_report_enabled']) || empty($settings['whatsapp_report_number']) || empty($settings['whatsapp_report_time'])) {
|
if (empty($settings['whatsapp_report_enabled']) || empty($settings['whatsapp_report_number']) || empty($settings['whatsapp_report_time'])) {
|
||||||
// Silent exit if disabled or missing config
|
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
$timezone = !empty($settings['timezone']) ? $settings['timezone'] : 'UTC';
|
$timezone = !empty($settings['timezone']) ? $settings['timezone'] : 'UTC';
|
||||||
date_default_timezone_set($timezone);
|
date_default_timezone_set($timezone);
|
||||||
|
|
||||||
$reportTime = $settings['whatsapp_report_time'];
|
// Sync MySQL Timezone
|
||||||
|
$pdo = db();
|
||||||
|
try {
|
||||||
|
$pdo->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';
|
$lastReportFile = __DIR__ . '/../storage/last_daily_report.txt';
|
||||||
$lastReportDate = file_exists($lastReportFile) ? trim(file_get_contents($lastReportFile)) : '';
|
$lastReportDate = file_exists($lastReportFile) ? trim(file_get_contents($lastReportFile)) : '';
|
||||||
|
|
||||||
$nowDt = new DateTime('now', new DateTimeZone($timezone));
|
$nowDt = new DateTime('now', new DateTimeZone($timezone));
|
||||||
|
|
||||||
|
// Target time for today
|
||||||
$targetTodayDt = clone $nowDt;
|
$targetTodayDt = clone $nowDt;
|
||||||
$timeParts = explode(':', $reportTime);
|
$timeParts = explode(':', $reportTime);
|
||||||
$targetTodayDt->setTime((int)$timeParts[0], (int)($timeParts[1] ?? 0), 0);
|
$targetTodayDt->setTime((int)$timeParts[0], (int)($timeParts[1] ?? 0), 0);
|
||||||
@ -42,40 +59,97 @@ try {
|
|||||||
if ($diffToday >= 0 && $diffToday <= 900 && $lastReportDate !== $nowDt->format('Y-m-d')) {
|
if ($diffToday >= 0 && $diffToday <= 900 && $lastReportDate !== $nowDt->format('Y-m-d')) {
|
||||||
cron_log("Condition met: sending daily report for " . $nowDt->format('Y-m-d'));
|
cron_log("Condition met: sending daily report for " . $nowDt->format('Y-m-d'));
|
||||||
|
|
||||||
$pdo = db();
|
|
||||||
$today = $nowDt->format('Y-m-d');
|
$today = $nowDt->format('Y-m-d');
|
||||||
|
$companyName = $settings['company_name'] ?? 'Company';
|
||||||
|
|
||||||
// 1. Calculate Stats
|
// --- 1. Global Stats ---
|
||||||
// Total Revenue Today
|
// 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 = $pdo->prepare("SELECT SUM(total_amount) FROM orders WHERE DATE(created_at) = ? AND status != 'cancelled'");
|
||||||
$stmt->execute([$today]);
|
$stmt->execute([$today]);
|
||||||
$revenueToday = $stmt->fetchColumn() ?: 0;
|
$totalRevenue = $stmt->fetchColumn() ?: 0;
|
||||||
|
|
||||||
// Total Orders Today
|
// Total Orders Today
|
||||||
$stmt = $pdo->prepare("SELECT COUNT(*) FROM orders WHERE DATE(created_at) = ? AND status != 'cancelled'");
|
$stmt = $pdo->prepare("SELECT COUNT(*) FROM orders WHERE DATE(created_at) = ? AND status != 'cancelled'");
|
||||||
$stmt->execute([$today]);
|
$stmt->execute([$today]);
|
||||||
$ordersToday = $stmt->fetchColumn();
|
$totalOrders = $stmt->fetchColumn() ?: 0;
|
||||||
|
|
||||||
// Total Expenses Today
|
// --- 2. Build Message Header ---
|
||||||
$stmt = $pdo->prepare("SELECT SUM(amount) FROM expenses WHERE DATE(expense_date) = ?");
|
$message = "📊 *Daily Summary Report* 📊\n";
|
||||||
$stmt->execute([$today]);
|
$message .= "🏢 *" . $companyName . "*\n";
|
||||||
$expensesToday = $stmt->fetchColumn() ?: 0;
|
$message .= "📅 Date: " . $today . "\n";
|
||||||
|
$message .= "--------------------------------\n";
|
||||||
// Currency
|
$message .= "🛒 *Total Orders:* " . $totalOrders . "\n";
|
||||||
$currency = $settings['currency_symbol'] ?? '$';
|
$message .= "💰 *Total Revenue:* " . format_currency_custom($totalRevenue, $settings) . "\n";
|
||||||
|
|
||||||
// 2. Format Message
|
// --- 3. Per-Outlet Stats ---
|
||||||
$message = "📅 *Daily Report* 📅\n";
|
// Get all active outlets
|
||||||
$message .= "Date: " . $today . "\n\n";
|
$stmtOutlets = $pdo->query("SELECT id, name FROM outlets WHERE is_deleted = 0 ORDER BY id ASC");
|
||||||
$message .= "💰 *Sales:* " . format_currency_simple($revenueToday, $settings) . "\n";
|
$outlets = $stmtOutlets->fetchAll();
|
||||||
$message .= "🧾 *Orders:* " . $ordersToday . "\n";
|
|
||||||
$message .= "💸 *Expenses:* " . format_currency_simple($expensesToday, $settings) . "\n";
|
|
||||||
$message .= "\n--------------------------\n";
|
|
||||||
$message .= "🤖 Auto-generated message";
|
|
||||||
|
|
||||||
// 3. Send Message
|
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);
|
$wablas = new WablasService($pdo);
|
||||||
// Handle multiple recipients (comma separated)
|
|
||||||
$recipients = explode(',', $settings['whatsapp_report_number']);
|
$recipients = explode(',', $settings['whatsapp_report_number']);
|
||||||
$anySuccess = false;
|
$anySuccess = false;
|
||||||
|
|
||||||
@ -83,7 +157,7 @@ try {
|
|||||||
$recipient = trim($recipient);
|
$recipient = trim($recipient);
|
||||||
if (empty($recipient)) continue;
|
if (empty($recipient)) continue;
|
||||||
|
|
||||||
cron_log("Sending report to: " . $recipient);
|
cron_log("Sending detailed report to: " . $recipient);
|
||||||
$result = $wablas->sendMessage($recipient, $message);
|
$result = $wablas->sendMessage($recipient, $message);
|
||||||
|
|
||||||
if (!empty($result['success']) && $result['success'] == true) {
|
if (!empty($result['success']) && $result['success'] == true) {
|
||||||
@ -98,17 +172,7 @@ try {
|
|||||||
file_put_contents($lastReportFile, $today);
|
file_put_contents($lastReportFile, $today);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Else: silent skip
|
|
||||||
|
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
cron_log("CRITICAL ERROR: " . $e->getMessage());
|
cron_log("CRITICAL ERROR: " . $e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
function format_currency_simple($amount, $settings) {
|
|
||||||
$symbol = $settings['currency_symbol'] ?? '$';
|
|
||||||
$decimals = (int)($settings['currency_decimals'] ?? 2);
|
|
||||||
$position = $settings['currency_position'] ?? 'before';
|
|
||||||
|
|
||||||
$formatted = number_format((float)$amount, $decimals);
|
|
||||||
return ($position === 'after') ? "$formatted $symbol" : "$symbol $formatted";
|
|
||||||
}
|
|
||||||
@ -21657,3 +21657,8 @@ Array
|
|||||||
[2026-03-25 06:18:01] Settings retrieved: {"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-25 01:59:39","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":"96897417667,96899359472","whatsapp_report_time":"23:59:00","whatsapp_report_enabled":1}
|
[2026-03-25 06:18:01] Settings retrieved: {"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-25 01:59:39","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":"96897417667,96899359472","whatsapp_report_time":"23:59:00","whatsapp_report_enabled":1}
|
||||||
[2026-03-25 06:18:01] Now: 2026-03-25 06:18:01 | Target: 2026-03-25 23:59:00 | Diff: -63659 | LastSent:
|
[2026-03-25 06:18:01] Now: 2026-03-25 06:18:01 | Target: 2026-03-25 23:59:00 | Diff: -63659 | LastSent:
|
||||||
[2026-03-25 06:18:01] Condition not met: skipping (Diff: -63659, LastSent: , Target: 23:59)
|
[2026-03-25 06:18:01] Condition not met: skipping (Diff: -63659, LastSent: , Target: 23:59)
|
||||||
|
[2026-03-25 23:59:01] Condition met: sending daily report for 2026-03-25
|
||||||
|
[2026-03-25 23:59:01] Sending report to: 96897417667
|
||||||
|
[2026-03-25 23:59:02] Report sent successfully to 96897417667
|
||||||
|
[2026-03-25 23:59:02] Sending report to: 96899359472
|
||||||
|
[2026-03-25 23:59:03] Report sent successfully to 96899359472
|
||||||
|
|||||||
1
storage/last_daily_report.txt
Normal file
1
storage/last_daily_report.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
2026-03-25
|
||||||
Loading…
x
Reference in New Issue
Block a user