# Struktur Tabel Retribusi PBG yang Dioptimalkan ## Ringkasan Optimasi Struktur tabel baru ini **lebih sederhana**, **fokus pada perhitungan**, dan **menghilangkan redundansi** dari struktur sebelumnya. ## Perbandingan Struktur ### SEBELUM (Kompleks) - `building_functions` - 8 kolom + relationship kompleks - `building_function_parameters` - 12 kolom dengan mismatch model/migration - `retribution_formulas` - Menyimpan formula sebagai string - `retribution_proposals` - 15+ kolom dengan banyak redundansi - `floor_height_indices` - OK, tidak berubah ### SESUDAH (Sederhana) - `building_types` - **7 kolom**, hierarki sederhana - `retribution_indices` - **6 kolom**, parameter calculation saja - `height_indices` - **3 kolom**, sama seperti sebelumnya - `retribution_configs` - **5 kolom**, konfigurasi global - `retribution_calculations` - **8 kolom**, hasil perhitungan saja --- ## Detail Struktur Tabel Baru ### 1. `building_types` **Fungsi:** Menyimpan jenis fungsi bangunan dengan hierarki sederhana | Kolom | Tipe | Keterangan | | ------------- | ------------ | ---------------------------------- | | `id` | bigint | Primary key | | `code` | varchar(10) | Kode unik (UMKM, KEAGAMAAN, dll) | | `name` | varchar(100) | Nama fungsi bangunan | | `parent_id` | bigint | ID parent (untuk hierarki) | | `level` | tinyint | Level hierarki (1=parent, 2=child) | | `coefficient` | decimal(8,4) | **Koefisien untuk perhitungan** | | `is_free` | boolean | **Apakah gratis (keagamaan, MBR)** | ### 2. `retribution_indices` **Fungsi:** Menyimpan parameter indeks untuk perhitungan (1:1 dengan building_types) | Kolom | Tipe | Keterangan | | ----------------------- | ------------ | ---------------------------------- | | `id` | bigint | Primary key | | `building_type_id` | bigint | FK ke building_types | | `ip_permanent` | decimal(8,4) | **Indeks Permanensi** | | `ip_complexity` | decimal(8,4) | **Indeks Kompleksitas** | | `locality_index` | decimal(8,4) | **Indeks Lokalitas** | | `infrastructure_factor` | decimal(8,4) | **Faktor prasarana (default 50%)** | ### 3. `height_indices` **Fungsi:** Indeks ketinggian per lantai (sama seperti sebelumnya) | Kolom | Tipe | Keterangan | | -------------- | ------------ | ---------------------------------------- | | `id` | bigint | Primary key | | `floor_number` | tinyint | Nomor lantai (1,2,3,4,5,6) | | `height_index` | decimal(8,6) | **IP Ketinggian (1.0, 1.09, 1.12, dst)** | ### 4. `retribution_configs` **Fungsi:** Konfigurasi global untuk perhitungan (menggantikan hard-coded values) | Kolom | Tipe | Keterangan | | ------------- | ------------- | --------------------- | | `id` | bigint | Primary key | | `key` | varchar(50) | Kunci konfigurasi | | `value` | decimal(15,2) | **Nilai konfigurasi** | | `description` | varchar(200) | Deskripsi | **Data yang disimpan:** - `BASE_VALUE` = 70350 (nilai dasar) - `INFRASTRUCTURE_MULTIPLIER` = 0.5 (50% prasarana) - `HEIGHT_MULTIPLIER` = 0.5 (pengali indeks ketinggian) ### 5. `retribution_calculations` **Fungsi:** Hasil perhitungan retribusi (history) | Kolom | Tipe | Keterangan | | -------------------- | ------------- | -------------------------------- | | `id` | bigint | Primary key | | `calculation_id` | varchar(20) | ID unik perhitungan | | `building_type_id` | bigint | FK ke building_types | | `floor_number` | tinyint | Lantai yang dipilih | | `building_area` | decimal(12,2) | **Luas bangunan input** | | `retribution_amount` | decimal(15,2) | **Hasil perhitungan** | | `calculation_detail` | json | **Detail breakdown perhitungan** | | `calculated_at` | timestamp | Waktu perhitungan | --- ## Formula Perhitungan ### Formula Excel yang Diimplementasikan: ``` H13 = coefficient * (ip_permanent + ip_complexity + (0.5 * height_index)) Main Calculation = building_area * (locality_index * BASE_VALUE * H13) Infrastructure = INFRASTRUCTURE_MULTIPLIER * Main Calculation Total Retribution = Main Calculation + Infrastructure ``` ### Implementasi dalam Service: ```php // Step 1: Calculate H13 coefficient $h13 = $buildingType->coefficient * ( $indices->ip_permanent + $indices->ip_complexity + (0.5 * $heightIndex) ); // Step 2: Main calculation $mainCalculation = $buildingArea * ($indices->locality_index * $baseValue * $h13); // Step 3: Infrastructure (50% additional) $infrastructureCalculation = 0.5 * $mainCalculation; // Step 4: Total $totalRetribution = $mainCalculation + $infrastructureCalculation; ``` --- ## Keuntungan Struktur Baru ### ✅ **Simplicity** - **5 tabel** vs 8+ tabel sebelumnya - **Kolom minimal** hanya yang diperlukan untuk perhitungan - **No redundant data** seperti ip_ketinggian di proposals ### ✅ **Performance** - **Proper indexes** untuk query yang sering digunakan - **Normalized structure** mengurangi storage - **Cached configs** untuk values yang jarang berubah ### ✅ **Maintainability** - **Clear separation** antara master data dan calculation results - **Configurable values** tidak hard-coded lagi - **Single responsibility** setiap tabel punya tujuan jelas ### ✅ **Flexibility** - **Easy to extend** untuk fungsi bangunan baru - **Configurable formulas** lewat RetributionConfig - **Audit trail** lewat calculation history ### ✅ **Data Integrity** - **Proper constraints** untuk validasi data - **Foreign key relationships** yang benar - **No model-migration mismatch** --- ## Migration Guide ### Langkah Implementasi: 1. **Run Migration:** `php artisan migrate` untuk tabel baru 2. **Seed Data:** Data master berdasarkan Excel akan otomatis ter-seed 3. **Update Code:** Ganti penggunaan model lama dengan model baru 4. **Test Calculation:** Verifikasi hasil perhitungan sama dengan Excel 5. **Deploy:** Struktur siap production ### Data Migration (Optional): Jika ada data existing di tabel lama yang perlu dipindahkan, buat script migration untuk transfer data dari struktur lama ke struktur baru. --- ## Usage Example ```php // Initialize service $calculator = new RetributionCalculatorService(); // Calculate retribution $result = $calculator->calculate( buildingTypeId: 8, // UMKM floorNumber: 2, // 2 lantai buildingArea: 100.50, // 100.5 m2 saveResult: true // Simpan ke database ); // Result structure [ 'building_type' => [...], 'total_retribution' => 31658.25, 'formatted_amount' => 'Rp 31,658.25', 'calculation_steps' => [...], 'calculation_id' => 'RTB-20250130140530-123' ] ``` Struktur ini **jauh lebih clean**, **mudah dipahami**, dan **optimal untuk perhitungan retribusi PBG**!