Files
lis/htdocs/app/Console/Commands/SyncPoliFromJson.php
T
2026-07-22 05:18:55 +07:00

125 lines
3.7 KiB
PHP

<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class SyncPoliFromJson extends Command
{
protected $signature = 'poli:sync-json {--path= : Path file JSON poli, default database/seeders/data/poli.json} {--dry-run : Cek data tanpa menulis ke database}';
protected $description = 'Update atau create data poli dari file JSON berdasarkan id tanpa truncate.';
public function handle(): int
{
$path = $this->resolvePath($this->option('path') ?: database_path('seeders/data/poli.json'));
$data = $this->readJson($path);
$updated = 0;
$created = 0;
$unchanged = 0;
DB::transaction(function () use ($data, &$updated, &$created, &$unchanged) {
foreach ($data as $row) {
$id = (int) $row['id'];
$payload = [
'poli' => $row['poli'] ?? null,
'subpoli' => $row['subpoli'] ?? null,
'subsubpoli' => $row['subsubpoli'] ?? null,
'modaliti' => $row['modaliti'] ?? null,
'kelompok' => $row['kelompok'] ?? null,
'modaliti2' => isset($row['modaliti2']) ? (string) $row['modaliti2'] : null,
'created_at' => $row['created_at'] ?? now(),
'updated_at' => $row['updated_at'] ?? now(),
];
$existing = DB::table('poli')->where('id', $id)->first();
if ($existing === null) {
$created++;
if (!$this->option('dry-run')) {
DB::table('poli')->insert(array_merge(['id' => $id], $payload));
}
continue;
}
if ($this->isSameRow($existing, $payload)) {
$unchanged++;
continue;
}
$updated++;
if (!$this->option('dry-run')) {
DB::table('poli')->where('id', $id)->update($payload);
}
}
});
$mode = $this->option('dry-run') ? 'DRY RUN' : 'DONE';
$this->info("{$mode}: {$created} created, {$updated} updated, {$unchanged} unchanged.");
return self::SUCCESS;
}
private function resolvePath(string $path): string
{
if ($path !== '' && $path[0] === '/') {
return $path;
}
return base_path($path);
}
private function readJson(string $path): array
{
if (!is_file($path)) {
throw new \RuntimeException("File JSON poli tidak ditemukan: {$path}");
}
$json = file_get_contents($path);
if ($json === false) {
throw new \RuntimeException("Gagal membaca file JSON poli: {$path}");
}
$data = json_decode($json, true);
if (!is_array($data)) {
throw new \RuntimeException("Format JSON poli tidak valid: {$path}");
}
$ids = [];
foreach ($data as $index => $row) {
if (!is_array($row) || !isset($row['id'])) {
throw new \RuntimeException('Data poli baris '.($index + 1).' tidak memiliki id.');
}
$id = (int) $row['id'];
if (isset($ids[$id])) {
throw new \RuntimeException("Duplikasi id poli pada JSON: {$id}");
}
$ids[$id] = true;
}
return $data;
}
private function isSameRow(object $existing, array $payload): bool
{
foreach ($payload as $key => $value) {
if ((string) ($existing->{$key} ?? '') !== (string) ($value ?? '')) {
return false;
}
}
return true;
}
}