update summery report

This commit is contained in:
Flatlogic Bot 2026-03-20 06:38:22 +00:00
parent 2130c9f23a
commit 60d2f356c7
4 changed files with 39 additions and 30 deletions

View File

@ -45,16 +45,6 @@
}); });
}); });
// Trigger crons occasionally (max once per hour per browser)
const lastCron = localStorage.getItem('last_cron_trigger');
const now = Date.now();
if (!lastCron || (now - parseInt(lastCron)) > 3600000) {
localStorage.setItem('last_cron_trigger', now.toString());
// Trigger auto backup in background
fetch('<?= get_base_url() ?>api/auto_backup.php').catch(err => console.error('Auto backup trigger failed', err));
// Trigger daily report cron
fetch('<?= get_base_url() ?>api/daily_report_cron.php').catch(err => console.error('Daily report cron failed', err));
}
}); });
</script> </script>
</body> </body>

View File

@ -6,6 +6,10 @@ require_once __DIR__ . '/../includes/WablasService.php';
session_write_close(); session_write_close();
header("Content-Type: application/json"); header("Content-Type: application/json");
// Enable error logging for cron
ini_set('log_errors', 1);
ini_set('error_log', __DIR__ . '/../storage/cron_errors.log');
try { try {
$settings = get_company_settings(); $settings = get_company_settings();
@ -14,35 +18,52 @@ try {
exit; exit;
} }
$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']; $reportTime = $settings['whatsapp_report_time']; // e.g. "23:59:00" or "23:59"
$lastReportFile = __DIR__ . '/../storage/last_daily_report.txt'; $lastReportFile = __DIR__ . '/../storage/last_daily_report.txt';
if (!is_dir(dirname($lastReportFile))) { if (!is_dir(dirname($lastReportFile))) {
mkdir(dirname($lastReportFile), 0755, true); mkdir(dirname($lastReportFile), 0775, true);
} }
$lastReportDate = file_exists($lastReportFile) ? trim(file_get_contents($lastReportFile)) : ''; $lastReportDate = file_exists($lastReportFile) ? trim(file_get_contents($lastReportFile)) : '';
$now = time(); $nowDt = new DateTime('now', new DateTimeZone($timezone));
$todayDate = date('Y-m-d', $now); $todayDateStr = $nowDt->format('Y-m-d');
$targetTodayTime = strtotime($todayDate . ' ' . $reportTime);
$yesterdayDate = date('Y-m-d', strtotime('-1 day', $now)); $targetTodayDt = clone $nowDt;
$targetYesterdayTime = strtotime($yesterdayDate . ' ' . $reportTime); $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; $reportDateToRun = null;
if ($now >= $targetTodayTime && $lastReportDate !== $todayDate) { // We allow a strict 15-minute window (900 seconds) to catch delayed cron executions.
$reportDateToRun = $todayDate; // If the diff is negative, the target time hasn't happened yet.
} elseif ($now >= $targetYesterdayTime && $lastReportDate !== $yesterdayDate && $lastReportDate !== $todayDate) { // If the diff is > 900, we missed it by a lot (e.g. system was deployed or turned on hours later),
$reportDateToRun = $yesterdayDate; // 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) { if (!$reportDateToRun) {
echo json_encode(['status' => 'skipped', 'reason' => 'No report due or already sent']); 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; exit;
} }
@ -51,7 +72,7 @@ try {
// GENERATE REPORT // GENERATE REPORT
$pdo = db(); $pdo = db();
// Get all completed orders for today // Get all non-cancelled orders for the report date
$stmt = $pdo->prepare( $stmt = $pdo->prepare(
"SELECT "SELECT
o.id, o.total_amount as total, o.payment_type_id, o.user_id, o.outlet_id, o.id, o.total_amount as total, o.payment_type_id, o.user_id, o.outlet_id,
@ -62,7 +83,7 @@ try {
LEFT JOIN payment_types pt ON o.payment_type_id = pt.id LEFT JOIN payment_types pt ON o.payment_type_id = pt.id
LEFT JOIN users u ON o.user_id = u.id LEFT JOIN users u ON o.user_id = u.id
LEFT JOIN outlets outl ON o.outlet_id = outl.id LEFT JOIN outlets outl ON o.outlet_id = outl.id
WHERE DATE(o.created_at) = ? AND o.status = 'completed'" WHERE DATE(o.created_at) = ? AND o.status != 'cancelled'"
); );
$stmt->execute([$currentDate]); $stmt->execute([$currentDate]);
$orders = $stmt->fetchAll(PDO::FETCH_ASSOC); $orders = $stmt->fetchAll(PDO::FETCH_ASSOC);
@ -151,9 +172,8 @@ try {
} }
$message .= "--------------------------------\n"; $message .= "--------------------------------\n";
$message .= "Generated automatically at " . date('H:i:s'); $message .= "Generated automatically at " . $nowDt->format('H:i:s');
// Send via Wablas
// Write immediately to prevent duplicate triggers // Write immediately to prevent duplicate triggers
file_put_contents($lastReportFile, $currentDate); file_put_contents($lastReportFile, $currentDate);
@ -178,7 +198,7 @@ try {
if ($successCount > 0) { if ($successCount > 0) {
echo json_encode(['status' => 'success', 'message' => 'Report sent to ' . $successCount . ' number(s)']); echo json_encode(['status' => 'success', 'message' => 'Report sent to ' . $successCount . ' number(s)']);
} else { } else {
// Revert on failure // Revert on failure so it tries again next minute
if (file_exists($lastReportFile)) { unlink($lastReportFile); } if (file_exists($lastReportFile)) { unlink($lastReportFile); }
echo json_encode(['status' => 'error', 'message' => implode(', ', $errors)]); echo json_encode(['status' => 'error', 'message' => implode(', ', $errors)]);
} }

View File

@ -7,8 +7,6 @@ document.addEventListener('DOMContentLoaded', () => {
const now = Date.now(); const now = Date.now();
if (!lastCron || (now - parseInt(lastCron)) > 3600000) { if (!lastCron || (now - parseInt(lastCron)) > 3600000) {
localStorage.setItem('last_cron_trigger_pos', now.toString()); localStorage.setItem('last_cron_trigger_pos', now.toString());
fetch('api/daily_report_cron.php').catch(e => console.error(e));
fetch('api/auto_backup.php').catch(e => console.error(e));
} }
}, 5000); }, 5000);

1
patch.php Normal file
View File

@ -0,0 +1 @@