Files
api-btekno/bin/check_and_fix_hourly_summary.php
BTekno Dev 19926b30e3 Fix: Data inconsistency pada transisi tahun/bulan dan setup API lokal
- Implementasi fallback mechanism untuk daily_summary (threshold 5%)
- Auto-detect base path untuk subdirectory installation
- Perbaikan query dengan CAST(? AS DATE) untuk semua tanggal
- Script utilities: check_daily_summary.php dan check_and_fix_hourly_summary.php
- Setup .htaccess untuk routing Slim Framework
- Test script untuk verifikasi API lokal
- Dokumentasi SETUP_LOCAL_API.md
2026-01-01 23:38:13 +07:00

125 lines
4.1 KiB
PHP
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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";