diff --git a/app/Http/Controllers/Data/PendudukController.php b/app/Http/Controllers/Data/PendudukController.php index 79e7b909a..ebff9d282 100644 --- a/app/Http/Controllers/Data/PendudukController.php +++ b/app/Http/Controllers/Data/PendudukController.php @@ -37,6 +37,7 @@ use App\Imports\ImporPendudukKeluarga; use App\Models\DataDesa; use App\Models\Penduduk; +use App\Services\PendudukService; use Illuminate\Http\Request; use Illuminate\Http\Response; use Illuminate\Support\Facades\DB; @@ -131,7 +132,53 @@ public function show($id) public function detail(Request $request) { - $penduduk = json_decode($request->data); + abort_if(!$request->filled('id'), 404); + + $data = (new PendudukService())->detailPenduduk($request->id); + + abort_if(empty($data), 404); + + $penduduk = (object) [ + 'id' => data_get($data, 'id'), + 'nama' => data_get($data, 'attributes.nama'), + 'nik' => data_get($data, 'attributes.nik'), + 'no_kk_sebelumnya' => data_get($data, 'attributes.no_kk_sebelumnya'), + 'hubungan_dalam_keluarga' => data_get($data, 'attributes.penduduk_hubungan.nama'), + 'jenis_kelamin' => data_get($data, 'attributes.jenis_kelamin.nama'), + 'agama' => data_get($data, 'attributes.agama.nama'), + 'status_penduduk' => data_get($data, 'attributes.penduduk_status.nama'), + 'akta_lahir' => data_get($data, 'attributes.akta_lahir'), + 'tempat_lahir' => data_get($data, 'attributes.tempatlahir'), + 'tanggal_lahir' => data_get($data, 'attributes.tanggallahir'), + 'wajib_ktp' => data_get($data, 'attributes.wajibKTP'), + 'status_rekam' => data_get($data, 'attributes.status_rekam_ktp.nama'), + 'elktp' => data_get($data, 'attributes.elKTP'), + 'pendidikan_dalam_kk' => data_get($data, 'attributes.pendidikan_k_k.nama'), + 'pendidikan_sedang_ditempuh' => data_get($data, 'attributes.pendidikan.nama'), + 'pekerjaan' => data_get($data, 'attributes.pekerjaan.nama'), + 'warga_negara' => data_get($data, 'attributes.warga_negara.nama'), + 'nomor_passport' => data_get($data, 'attributes.dokumen_pasport'), + 'tanggal_akhir_passport' => data_get($data, 'attributes.tanggal_akhir_paspor'), + 'nomor_kitas' => data_get($data, 'attributes.dokumen_kitas'), + 'nik_ayah' => data_get($data, 'attributes.ayah_nik'), + 'nama_ayah' => data_get($data, 'attributes.nama_ayah'), + 'nik_ibu' => data_get($data, 'attributes.ibu_nik'), + 'nama_ibu' => data_get($data, 'attributes.nama_ibu'), + 'nomor_telepon' => data_get($data, 'attributes.telepon'), + 'alamat_sebelumnya' => data_get($data, 'attributes.alamat_sebelumnya'), + 'alamat_sekarang' => data_get($data, 'attributes.alamat_sekarang'), + 'status_kawin' => data_get($data, 'attributes.status_kawin.nama'), + 'no_akta_nikah' => data_get($data, 'attributes.akta_perkawinan'), + 'tanggal_nikah' => data_get($data, 'attributes.tanggalperkawinan'), + 'akta_perceraian' => data_get($data, 'attributes.akta_perceraian'), + 'tanggal_perceraian' => data_get($data, 'attributes.tanggalperceraian'), + 'golongan_darah' => data_get($data, 'attributes.golongan_darah.nama'), + 'cacat' => data_get($data, 'attributes.cacat.nama'), + 'sakit_menahun' => data_get($data, 'attributes.sakit_menahun.nama'), + 'cara_kb' => data_get($data, 'attributes.kb.nama'), + 'status_kehamilan' => data_get($data, 'attributes.statusHamil'), + ]; + $page_title = 'Detail Penduduk'; $page_description = 'Detail Data Penduduk: ' . ucwords(strtolower($penduduk->nama)); diff --git a/app/Services/PendudukService.php b/app/Services/PendudukService.php index 488300c29..eea844f7b 100644 --- a/app/Services/PendudukService.php +++ b/app/Services/PendudukService.php @@ -94,6 +94,20 @@ public function exportPenduduk($size, $number, $search) }); } + public function detailPenduduk($id) + { + $data = $this->apiRequest('/api/v1/penduduk', [ + 'filter[id]' => $id, + 'page[size]' => 1, + ]); + + if (isset($data['attributes'])) { + return $data; + } + + return $data[0] ?? null; + } + /** * Export Data Penduduk */ diff --git a/catatan_rilis.md b/catatan_rilis.md index 0fa9015ee..0c6fc3b51 100644 --- a/catatan_rilis.md +++ b/catatan_rilis.md @@ -31,3 +31,4 @@ Terimakasih [isi disini] yang telah berkontribusi langsung mengembangkan aplikas 9. [#1527](https://github.com/OpenSID/OpenDK/issues/1527) Fix WAF Blocking di datatables dengan ubah GET ke POST di Menu Admin SIKEMA -> Daftar Keluhan 10. [#1485](https://github.com/OpenSID/OpenDK/issues/1485) Perbaikan Dependecy bot Security 11. [#1556](https://github.com/OpenSID/OpenDK/issues/1556) Perbaikan Blade Prettier +12. [#1550](https://github.com/OpenSID/OpenDK/issues/1550) Sederhanakan Url detail penduduk di menu Data->Kependudukan->Penduduk->Detail diff --git a/resources/views/data/penduduk/gabungan/index.blade.php b/resources/views/data/penduduk/gabungan/index.blade.php index 0a99f1672..f72f510a3 100644 --- a/resources/views/data/penduduk/gabungan/index.blade.php +++ b/resources/views/data/penduduk/gabungan/index.blade.php @@ -94,54 +94,9 @@ }, columns: [{ data: function(data) { - let d = data.attributes - let obj = { - 'id': data.id, - 'nama': d.nama, - 'nik': d.nik, - 'no_kk_sebelumnya': d.no_kk_sebelumnya, - 'hubungan_dalam_keluarga': d.penduduk_hubungan?.nama ?? null, - 'jenis_kelamin': d.jenis_kelamin?.nama ?? null, - 'agama': d.agama.nama, - 'status_penduduk': d.penduduk_status?.nama ?? null, - 'akta_lahir': d.akta_lahir, - 'tempat_lahir': d.tempatlahir, - 'tanggal_lahir': d.tanggallahir, - 'tanggal_lahir': d.tanggallahir, - 'wajib_ktp': d.wajibKTP, - 'status_rekam': d.status_rekam_ktp?.nama ?? null, - 'elktp': d.elKTP, - 'pendidikan_dalam_kk': d.pendidikan_k_k?.nama ?? null, - 'pendidikan_sedang_ditempuh': d.pendidikan?.nama ?? null, - 'pekerjaan': d.pekerjaan?.nama ?? null, - 'warga_negara': d.warga_negara?.nama ?? null, - 'nomor_passport': d.dokumen_pasport, - 'tanggal_akhir_passport': d.tanggal_akhir_paspor, - 'nomor_kitas': d.dokumen_kitas, - 'nik_ayah': d.ayah_nik, - 'nama_ayah': d.nama_ayah, - 'nik_ibu': d.ibu_nik, - 'nama_ibu': d.nama_ibu, - 'nomor_telepon': d.telepon, - 'alamat_sebelumnya': d.alamat_sebelumnya, - 'alamat_sekarang': d.alamat_sekarang, - 'status_kawin': d.status_kawin?.nama ?? null, - 'no_akta_nikah': d.akta_perkawinan, - 'tanggal_nikah': d.tanggalperkawinan, - 'akta_perceraian': d.akta_perceraian, - 'tanggal_perceraian': d.tanggalperceraian, - 'golongan_darah': d.golongan_darah?.nama ?? null, - 'cacat': d.cacat?.nama ?? null, - 'sakit_menahun': d.sakit_menahun?.nama ?? null, - 'cara_kb': d.kb?.nama ?? null, - 'status_kehamilan': d.statusHamil - } - - let jsonData = encodeURIComponent(JSON.stringify(obj)); - const _url = data.attributes.path === undefined ? - "{{ route('data.penduduk.detail', ['data' => '__DATA__']) }}" - .replace('__DATA__', jsonData) : + "{{ route('data.penduduk.detail', ['id' => '__ID__']) }}" + .replace('__ID__', encodeURIComponent(data.id)) : `{{ url('data/penduduk/show') }}/${data.id}` return ` diff --git a/tests/Feature/Controllers/Data/PendudukDetailControllerTest.php b/tests/Feature/Controllers/Data/PendudukDetailControllerTest.php new file mode 100644 index 000000000..f9bd96892 --- /dev/null +++ b/tests/Feature/Controllers/Data/PendudukDetailControllerTest.php @@ -0,0 +1,93 @@ + 'api_server_database_gabungan'], + ['value' => 'http://localhost:8000'] + ); + SettingAplikasi::updateOrCreate( + ['key' => 'api_key_database_gabungan'], + ['value' => 'test-api-key'] + ); + SettingAplikasi::updateOrCreate( + ['key' => 'sinkronisasi_database_gabungan'], + ['value' => '1'] + ); +}); + +test('detail aborts 404 when id is missing', function () { + $request = new Request(); + + try { + (new PendudukController())->detail($request); + $this->fail('Expected HttpException was not thrown'); + } catch (\Symfony\Component\HttpKernel\Exception\HttpException $e) { + expect($e->getStatusCode())->toBe(404); + } +}); + +test('detail aborts 404 when penduduk not found', function () { + Http::fake([ + '*/api/v1/penduduk*' => Http::response(['data' => []], 200) + ]); + + $request = new Request(['id' => 999]); + + try { + (new PendudukController())->detail($request); + $this->fail('Expected HttpException was not thrown'); + } catch (\Symfony\Component\HttpKernel\Exception\HttpException $e) { + expect($e->getStatusCode())->toBe(404); + } +}); + +test('detail returns view with penduduk data', function () { + Http::fake([ + '*/api/v1/penduduk*' => Http::response([ + 'data' => [ + 'id' => 1, + 'attributes' => [ + 'nama' => 'John Doe', + 'nik' => '1234567890123456', + 'penduduk_hubungan' => ['nama' => 'Kepala Keluarga'], + 'jenis_kelamin' => ['nama' => 'LAKI-LAKI'], + 'agama' => ['nama' => 'Islam'], + 'penduduk_status' => ['nama' => 'Tetap'], + 'tempatlahir' => 'Jakarta', + 'tanggallahir' => '1990-01-01', + 'wajibKTP' => 'Ya', + 'status_rekam_ktp' => ['nama' => 'Sudah Rekam'], + 'elKTP' => '1', + 'pendidikan_k_k' => ['nama' => 'SMA'], + 'pendidikan' => ['nama' => 'SMA'], + 'pekerjaan' => ['nama' => 'Pegawai'], + 'warga_negara' => ['nama' => 'WNI'], + 'telepon' => '08123456789', + 'alamat_sekarang' => 'Jl. Test No. 1', + 'status_kawin' => ['nama' => 'Belum Kawin'], + 'golongan_darah' => ['nama' => 'O'], + 'cacat' => ['nama' => 'Tidak Ada'], + 'sakit_menahun' => ['nama' => 'Tidak Ada'], + 'kb' => ['nama' => 'Tidak Menggunakan'], + ] + ] + ], 200) + ]); + + $request = new Request(['id' => 1]); + $response = (new PendudukController())->detail($request); + + expect($response)->toBeInstanceOf(\Illuminate\Contracts\View\View::class); + expect($response->getName())->toBe('data.penduduk.gabungan.show'); + expect($response->getData()['penduduk']->id)->toBe(1); + expect($response->getData()['penduduk']->nama)->toBe('John Doe'); + expect($response->getData()['penduduk']->nik)->toBe('1234567890123456'); +}); diff --git a/tests/Unit/Services/PendudukServiceTest.php b/tests/Unit/Services/PendudukServiceTest.php index 5d6418b96..de4fabc91 100644 --- a/tests/Unit/Services/PendudukServiceTest.php +++ b/tests/Unit/Services/PendudukServiceTest.php @@ -190,6 +190,76 @@ expect($penduduk)->toBeNull(); }); +// detailPenduduk tests + +it('can get detail penduduk when API returns single object', function () { + Http::fake([ + '*/api/v1/penduduk*' => Http::response([ + 'data' => [ + 'id' => 1, + 'attributes' => [ + 'nama' => 'John Doe', + 'nik' => '1234567890123456', + ] + ] + ], 200) + ]); + + $service = new PendudukService(); + $result = $service->detailPenduduk(1); + + expect($result)->not->toBeNull(); + expect($result['id'])->toBe(1); + expect($result['attributes']['nama'])->toBe('John Doe'); +}); + +it('can get detail penduduk when API returns array', function () { + Http::fake([ + '*/api/v1/penduduk*' => Http::response([ + 'data' => [ + [ + 'id' => 1, + 'attributes' => [ + 'nama' => 'Jane Doe', + 'nik' => '9876543210987654', + ] + ] + ] + ], 200) + ]); + + $service = new PendudukService(); + $result = $service->detailPenduduk(1); + + expect($result)->not->toBeNull(); + expect($result['id'])->toBe(1); + expect($result['attributes']['nama'])->toBe('Jane Doe'); +}); + +it('returns null when penduduk not found', function () { + Http::fake([ + '*/api/v1/penduduk*' => Http::response([ + 'data' => [] + ], 200) + ]); + + $service = new PendudukService(); + $result = $service->detailPenduduk(999); + + expect($result)->toBeNull(); +}); + +it('returns null when API returns empty', function () { + Http::fake([ + '*/api/v1/penduduk*' => Http::response([], 200) + ]); + + $service = new PendudukService(); + $result = $service->detailPenduduk(1); + + expect($result)->toBeNull(); +}); + it('can apply filters to jumlah penduduk', function () { Http::fake([ '*/api/v1/opendk/sync-penduduk-opendk*' => Http::response([