Files
sibedas/app/Console/Commands/TestRetributionData.php
2025-06-18 22:53:44 +07:00

291 lines
10 KiB
PHP
Raw 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.
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Models\BuildingType;
use App\Models\RetributionIndex;
use App\Models\HeightIndex;
use App\Models\RetributionConfig;
use App\Models\RetributionCalculation;
use App\Services\RetributionCalculatorService;
class TestRetributionData extends Command
{
protected $signature = 'retribution:data
{--save : Save calculation results to database}
{--show : Show existing data and relations}
{--clear : Clear calculation history}';
protected $description = 'Test retribution data storage and display database relations';
protected $calculatorService;
public function __construct(RetributionCalculatorService $calculatorService)
{
parent::__construct();
$this->calculatorService = $calculatorService;
}
public function handle()
{
$this->info('🗄️ SISTEM TEST DATA & RELASI RETRIBUSI PBG');
$this->info('=' . str_repeat('=', 55));
if ($this->option('clear')) {
$this->clearCalculationHistory();
return;
}
if ($this->option('show')) {
$this->showExistingData();
return;
}
if ($this->option('save')) {
$this->saveTestCalculations();
}
$this->showDatabaseStructure();
$this->showSampleData();
$this->showRelations();
}
protected function saveTestCalculations()
{
$this->info('💾 MENYIMPAN SAMPLE CALCULATIONS...');
$this->line('');
$testCases = [
['type_code' => 'KEAGAMAAN', 'area' => 200, 'floor' => 1],
['type_code' => 'SOSBUDAYA', 'area' => 150, 'floor' => 2],
['type_code' => 'CAMP_KECIL', 'area' => 1, 'floor' => 1],
['type_code' => 'UMKM', 'area' => 100, 'floor' => 2],
['type_code' => 'HUN_SEDH', 'area' => 80, 'floor' => 1],
['type_code' => 'USH_BESAR', 'area' => 500, 'floor' => 3],
];
foreach ($testCases as $case) {
$buildingType = BuildingType::where('code', $case['type_code'])->first();
if (!$buildingType) {
$this->warn("⚠️ Building type {$case['type_code']} not found");
continue;
}
$result = $this->calculatorService->calculate(
$buildingType->id,
$case['floor'],
$case['area']
);
// Save to database
RetributionCalculation::create([
'calculation_id' => 'TST' . now()->format('ymdHis') . rand(10, 99),
'building_type_id' => $buildingType->id,
'floor_number' => $case['floor'],
'building_area' => $case['area'],
'retribution_amount' => $result['total_retribution'],
'calculation_detail' => json_encode($result),
'calculated_at' => now()
]);
$this->info("✅ Saved: {$buildingType->name} - {$case['area']}m² - {$case['floor']} lantai - Rp " . number_format($result['total_retribution']));
}
$this->line('');
$this->info('💾 Sample calculations saved successfully!');
$this->line('');
}
protected function showExistingData()
{
$this->info('📊 DATA YANG TERSIMPAN DI DATABASE');
$this->info('=' . str_repeat('=', 40));
$calculations = RetributionCalculation::with('buildingType')
->orderBy('created_at', 'desc')
->limit(10)
->get();
if ($calculations->isEmpty()) {
$this->warn('❌ Tidak ada data calculation yang tersimpan');
$this->info('💡 Gunakan --save untuk menyimpan sample data');
return;
}
$headers = ['ID', 'Building Type', 'Area', 'Floor', 'Amount', 'Created'];
$rows = [];
foreach ($calculations as $calc) {
$rows[] = [
substr($calc->calculation_id, -8),
$calc->buildingType->name ?? 'N/A',
$calc->building_area . ' m²',
$calc->floor_number,
'Rp ' . number_format($calc->retribution_amount),
$calc->created_at->format('d/m H:i')
];
}
$this->table($headers, $rows);
}
protected function clearCalculationHistory()
{
$count = RetributionCalculation::count();
if ($count === 0) {
$this->info(' Tidak ada data calculation untuk dihapus');
return;
}
if ($this->confirm("🗑️ Hapus {$count} calculation records?")) {
RetributionCalculation::truncate();
$this->info("{$count} calculation records berhasil dihapus");
}
}
protected function showDatabaseStructure()
{
$this->info('🏗️ STRUKTUR DATABASE RETRIBUSI');
$this->info('=' . str_repeat('=', 35));
$tables = [
'building_types' => 'Hierarki dan metadata building types',
'retribution_indices' => 'Parameter perhitungan (coefficient, IP, dll)',
'height_indices' => 'Koefisien tinggi berdasarkan lantai',
'retribution_configs' => 'Konfigurasi global (base value, dll)',
'retribution_calculations' => 'History perhitungan dan hasil'
];
foreach ($tables as $table => $description) {
$this->line("📋 <info>{$table}</info>: {$description}");
}
$this->line('');
}
protected function showSampleData()
{
$this->info('📋 SAMPLE DATA DARI SETIAP TABEL');
$this->info('=' . str_repeat('=', 35));
// Building Types
$this->line('<comment>🏢 BUILDING TYPES:</comment>');
$buildingTypes = BuildingType::select('id', 'code', 'name', 'level', 'is_free')
->orderBy('level')
->orderBy('name')
->get();
$headers = ['ID', 'Code', 'Name', 'Level', 'Free'];
$rows = [];
foreach ($buildingTypes->take(5) as $type) {
$rows[] = [
$type->id,
$type->code,
substr($type->name, 0, 25) . '...',
$type->level,
$type->is_free ? '✅' : '❌'
];
}
$this->table($headers, $rows);
// Retribution Indices
$this->line('<comment>📊 RETRIBUTION INDICES:</comment>');
$indices = RetributionIndex::with('buildingType')
->select('building_type_id', 'coefficient', 'ip_permanent', 'ip_complexity', 'locality_index')
->get();
$headers = ['Building Type', 'Coefficient', 'IP Permanent', 'IP Complexity', 'Locality'];
$rows = [];
foreach ($indices->take(5) as $index) {
$rows[] = [
$index->buildingType->code ?? 'N/A',
number_format($index->coefficient, 4),
number_format($index->ip_permanent, 4),
number_format($index->ip_complexity, 4),
number_format($index->locality_index, 4)
];
}
$this->table($headers, $rows);
// Height Indices
$this->line('<comment>🏗️ HEIGHT INDICES:</comment>');
$heights = HeightIndex::orderBy('floor_number')->get();
$headers = ['Floor', 'Height Index'];
$rows = [];
foreach ($heights as $height) {
$rows[] = [
$height->floor_number,
number_format($height->height_index, 4)
];
}
$this->table($headers, $rows);
// Retribution Configs
$this->line('<comment>⚙️ RETRIBUTION CONFIGS:</comment>');
$configs = RetributionConfig::all();
$headers = ['Key', 'Value', 'Description'];
$rows = [];
foreach ($configs as $config) {
$rows[] = [
$config->key,
$config->value,
substr($config->description ?? '', 0, 30) . '...'
];
}
$this->table($headers, $rows);
}
protected function showRelations()
{
$this->info('🔗 RELASI ANTAR TABEL');
$this->info('=' . str_repeat('=', 25));
// Test relations dengan sample data
$buildingType = BuildingType::with(['indices', 'calculations'])
->where('code', 'UMKM')
->first();
if (!$buildingType) {
$this->warn('⚠️ Sample building type tidak ditemukan');
return;
}
$this->line("<comment>🏢 Building Type: {$buildingType->name}</comment>");
$this->line(" 📋 Code: {$buildingType->code}");
$this->line(" 📊 Level: {$buildingType->level}");
$this->line(" 🆓 Free: " . ($buildingType->is_free ? 'Ya' : 'Tidak'));
// Show indices relation
if ($buildingType->indices) {
$index = $buildingType->indices;
$this->line(" <comment>📊 Retribution Index:</comment>");
$this->line(" 💰 Coefficient: " . number_format($index->coefficient, 4));
$this->line(" 🏗️ IP Permanent: " . number_format($index->ip_permanent, 4));
$this->line(" 🔧 IP Complexity: " . number_format($index->ip_complexity, 4));
$this->line(" 📍 Locality Index: " . number_format($index->locality_index, 4));
}
// Show calculations relation
$calculationsCount = $buildingType->calculations()->count();
$this->line(" <comment>📈 Calculations: {$calculationsCount} records</comment>");
if ($calculationsCount > 0) {
$latestCalc = $buildingType->calculations()->latest()->first();
$this->line(" 📅 Latest: " . $latestCalc->created_at->format('d/m/Y H:i'));
$this->line(" 💰 Amount: Rp " . number_format($latestCalc->retribution_amount));
}
$this->line('');
$this->info('🎯 KESIMPULAN RELASI:');
$this->line(' • BuildingType hasOne RetributionIndex');
$this->line(' • BuildingType hasMany RetributionCalculations');
$this->line(' • RetributionCalculation belongsTo BuildingType');
$this->line(' • HeightIndex independent (digunakan berdasarkan floor_number)');
$this->line(' • RetributionConfig global settings');
}
}