Files
api-btekno/bin/check_and_fix_hourly_summary.php

125 lines
4.1 KiB
PHP
Raw Normal View History

#!/usr/bin/env php
<?php
/**
* Script untuk check dan fix data hourly_summary yang tidak valid
*
* Usage:
* php bin/check_and_fix_hourly_summary.php [date]
*
* Examples:
* php bin/check_and_fix_hourly_summary.php 2026-01-01
* php bin/check_and_fix_hourly_summary.php # Check semua tanggal
*/
require __DIR__ . '/../vendor/autoload.php';
use App\Config\AppConfig;
use App\Support\Database;
use App\Modules\Retribusi\Summary\HourlySummaryService;
AppConfig::loadEnv(__DIR__ . '/..');
$db = Database::getConnection(
AppConfig::get('DB_HOST'),
AppConfig::get('DB_NAME'),
AppConfig::get('DB_USER'),
AppConfig::get('DB_PASS')
);
$service = new HourlySummaryService($db);
// Get date from command line or check all dates
$dateInput = $argv[1] ?? null;
if ($dateInput) {
// Validate date format
$dateTime = DateTime::createFromFormat('Y-m-d', $dateInput);
if ($dateTime === false || $dateTime->format('Y-m-d') !== $dateInput) {
echo "Error: Invalid date format. Expected Y-m-d (e.g., 2026-01-01)\n";
exit(1);
}
$dates = [$dateInput];
} else {
// Get all unique dates from hourly_summary
$stmt = $db->query("SELECT DISTINCT summary_date FROM hourly_summary ORDER BY summary_date DESC LIMIT 30");
$dates = [];
foreach ($stmt->fetchAll() as $row) {
$dates[] = $row['summary_date'];
}
if (empty($dates)) {
echo "No dates found in hourly_summary table.\n";
exit(0);
}
}
echo "=== Checking and Fixing hourly_summary ===\n\n";
foreach ($dates as $date) {
echo "--- Date: $date ---\n";
// Check entry_events count
$stmt = $db->prepare('
SELECT COUNT(*) as total_count
FROM entry_events e
INNER JOIN locations l ON e.location_code = l.code AND l.is_active = 1
INNER JOIN gates g ON e.location_code = g.location_code
AND e.gate_code = g.gate_code
AND g.is_active = 1
WHERE DATE(e.event_time) = CAST(? AS DATE)
');
$stmt->execute([$date]);
$entryResult = $stmt->fetch();
$entryCount = (int) ($entryResult['total_count'] ?? 0);
// Check hourly_summary count
$stmt = $db->prepare('
SELECT SUM(total_count) as total_count
FROM hourly_summary
WHERE summary_date = CAST(? AS DATE)
');
$stmt->execute([$date]);
$summaryResult = $stmt->fetch();
$summaryCount = (int) ($summaryResult['total_count'] ?? 0);
echo " entry_events: $entryCount events\n";
echo " hourly_summary: $summaryCount events\n";
if ($entryCount > 0 && $summaryCount == 0) {
echo " ❌ PROBLEM: entry_events has data but hourly_summary is empty!\n";
echo " → Running aggregation...\n";
try {
$result = $service->aggregateForDate($date);
echo " ✓ Aggregation completed: {$result['rows_processed']} rows processed\n";
} catch (Exception $e) {
echo " ✗ Error: " . $e->getMessage() . "\n";
}
} elseif ($entryCount > 0 && $summaryCount > 0 && abs($entryCount - $summaryCount) > ($entryCount * 0.1)) {
// Perbedaan lebih dari 10%
$diff = abs($entryCount - $summaryCount);
$diffPercent = ($diff / max($entryCount, $summaryCount)) * 100;
echo " ⚠️ WARNING: Count mismatch! Difference: $diff ($diffPercent%)\n";
if ($diffPercent > 50) {
echo " → Re-running aggregation to fix...\n";
try {
$result = $service->aggregateForDate($date);
echo " ✓ Re-aggregation completed: {$result['rows_processed']} rows processed\n";
} catch (Exception $e) {
echo " ✗ Error: " . $e->getMessage() . "\n";
}
}
} elseif ($entryCount > 0 && $summaryCount > 0) {
echo " ✓ OK: Counts match\n";
} elseif ($entryCount == 0 && $summaryCount == 0) {
echo " No data for this date\n";
} elseif ($entryCount == 0 && $summaryCount > 0) {
echo " ⚠️ WARNING: hourly_summary has data but entry_events is empty (orphaned data)\n";
}
echo "\n";
}
echo "Done!\n";