From 5b235def37c8f25fd8f426d7b5348dbebf0ac558 Mon Sep 17 00:00:00 2001 From: Daeng Deni Mardaeni Date: Thu, 10 Jul 2025 14:33:26 +0700 Subject: [PATCH] feat(webstatement): tambah field password untuk proteksi PDF statement Perubahan yang dilakukan: - Menambahkan kolom password (nullable) pada tabel print_statement_logs melalui migrasi baru. - Menambahkan field password di model PrintStatementLog dengan atribut hidden untuk keamanan serialisasi. - Menambahkan input password pada form request print statement. - Menambahkan validasi sisi klien agar password minimal 6 karakter. - Menambahkan konfirmasi melalui SweetAlert untuk pengisian password dan email tujuan. - Menambahkan index pada kolom password untuk optimasi pencarian jika dibutuhkan. - Menggunakan field password untuk proteksi file PDF melalui PDFPasswordProtect. - Menambahkan helper text dan placeholder pada form untuk meningkatkan pengalaman pengguna. - Menambahkan atribut autocomplete="new-password" untuk menghindari autofill browser yang tidak aman. - Menjaga kompatibilitas ke belakang dengan membuat field bersifat opsional (nullable). Tujuan perubahan: - Memberikan opsi proteksi file PDF dengan password yang diatur oleh pengguna. - Meningkatkan keamanan distribusi file statement melalui email. - Memastikan pengalaman pengguna tetap aman dan nyaman saat mengatur proteksi. --- .../Controllers/PrintStatementController.php | 2 +- app/Models/PrintStatementLog.php | 5 ++ ...password_to_print_statement_logs_table.php | 41 +++++++++ resources/views/statements/index.blade.php | 87 ++++++++++++++----- 4 files changed, 110 insertions(+), 25 deletions(-) create mode 100644 database/migrations/2025_07_10_071722_add_password_to_print_statement_logs_table.php diff --git a/app/Http/Controllers/PrintStatementController.php b/app/Http/Controllers/PrintStatementController.php index 724bbbb..90487e3 100644 --- a/app/Http/Controllers/PrintStatementController.php +++ b/app/Http/Controllers/PrintStatementController.php @@ -110,7 +110,7 @@ ini_set('max_execution_time', 300000); $validated['failed_count'] = 0; $validated['stmt_sent_type'] = $request->input('stmt_sent_type') ? implode(",",$request->input('stmt_sent_type')) : ''; $validated['branch_code'] = $validated['branch_code'] ?? $branch_code; // Awal tidak tersedia - + $validated['password'] = $request->input('password') ?? ''; // Create the statement log $statement = PrintStatementLog::create($validated); diff --git a/app/Models/PrintStatementLog.php b/app/Models/PrintStatementLog.php index 23ef1d7..55b2fa7 100644 --- a/app/Models/PrintStatementLog.php +++ b/app/Models/PrintStatementLog.php @@ -46,6 +46,7 @@ class PrintStatementLog extends Model 'email_sent_at', 'stmt_sent_type', 'is_generated', + 'password', // Tambahan field password ]; protected $casts = [ @@ -60,6 +61,10 @@ class PrintStatementLog extends Model 'target_accounts' => 'array', ]; + protected $hidden = [ + 'password', // Hide password dari serialization + ]; + /** * Get the formatted period display * diff --git a/database/migrations/2025_07_10_071722_add_password_to_print_statement_logs_table.php b/database/migrations/2025_07_10_071722_add_password_to_print_statement_logs_table.php new file mode 100644 index 0000000..4032d15 --- /dev/null +++ b/database/migrations/2025_07_10_071722_add_password_to_print_statement_logs_table.php @@ -0,0 +1,41 @@ +string('password', 255)->nullable()->after('stmt_sent_type') + ->comment('Password untuk proteksi PDF statement'); + + // Menambahkan index untuk performa query jika diperlukan + $table->index(['password'], 'idx_print_statement_logs_password'); + }); + } + + /** + * Membalikkan migrasi dengan menghapus kolom password + * + * @return void + */ + public function down(): void + { + Schema::table('print_statement_logs', function (Blueprint $table) { + // Hapus index terlebih dahulu + $table->dropIndex('idx_print_statement_logs_password'); + + // Hapus kolom password + $table->dropColumn('password'); + }); + } +}; diff --git a/resources/views/statements/index.blade.php b/resources/views/statements/index.blade.php index 5c46646..8d5d67f 100644 --- a/resources/views/statements/index.blade.php +++ b/resources/views/statements/index.blade.php @@ -20,7 +20,7 @@ @endif
- @if ($multiBranch) + @if (!$multiBranch)
+
+ + Jika dikosongkan password default statement akan diberlakukan +
+ @error('password') +
{{ $message }}
+ @enderror +
+
@@ -141,7 +157,8 @@
+ data-datatable-state-save="false" id="statement-table" + data-api-url="{{ route('statements.datatables') }}">
per page - - per page
@@ -273,51 +287,76 @@ } /** - * Konfirmasi email sebelum submit form - * Menampilkan SweetAlert jika email diisi untuk konfirmasi pengiriman + * Konfirmasi password dan email sebelum submit form + * Menampilkan SweetAlert jika password atau email diisi untuk konfirmasi */ document.addEventListener('DOMContentLoaded', function() { const form = document.querySelector('form'); const emailInput = document.getElementById('email'); + const passwordInput = document.getElementById('password'); - // Log: Inisialisasi event listener untuk konfirmasi email - console.log('Email confirmation listener initialized'); + // Log: Inisialisasi event listener untuk konfirmasi + console.log('Form confirmation listener initialized'); form.addEventListener('submit', function(e) { const emailValue = emailInput.value.trim(); + const passwordValue = passwordInput.value.trim(); - // Jika email diisi, tampilkan konfirmasi + let confirmationNeeded = false; + let confirmationMessage = ''; + + // Jika email diisi if (emailValue) { + confirmationNeeded = true; + confirmationMessage += `• Statement akan dikirim ke email: ${emailValue}\n`; + } + + // Jika password diisi + if (passwordValue) { + confirmationNeeded = true; + confirmationMessage += `• PDF akan diproteksi dengan password\n`; + } + + // Jika ada yang perlu dikonfirmasi + if (confirmationNeeded) { e.preventDefault(); // Hentikan submit form sementara - // Log: Email terdeteksi, menampilkan konfirmasi - console.log('Email detected:', emailValue); + // Log: Konfirmasi diperlukan + console.log('Confirmation needed:', { + email: emailValue, + hasPassword: !!passwordValue + }); Swal.fire({ - title: 'Konfirmasi Pengiriman Email', - text: `Apakah Anda yakin ingin mengirimkan statement ke email: ${emailValue}?`, + title: 'Konfirmasi Request Statement', + text: `Mohon konfirmasi pengaturan berikut:\n\n${confirmationMessage}\nApakah Anda yakin ingin melanjutkan?`, icon: 'question', showCancelButton: true, confirmButtonColor: '#3085d6', cancelButtonColor: '#d33', - confirmButtonText: 'Ya, Kirim Email', + confirmButtonText: 'Ya, Lanjutkan', cancelButtonText: 'Batal', - reverseButtons: true + reverseButtons: true, + preConfirm: () => { + // Validasi password jika diisi + if (passwordValue && passwordValue.length < 6) { + Swal.showValidationMessage('Password minimal 6 karakter'); + return false; + } + return true; + } }).then((result) => { if (result.isConfirmed) { - // Log: User konfirmasi pengiriman email - console.log('User confirmed email sending'); + // Log: User konfirmasi + console.log('User confirmed form submission'); // Submit form setelah konfirmasi form.submit(); } else { - // Log: User membatalkan pengiriman email - console.log('User cancelled email sending'); + // Log: User membatalkan + console.log('User cancelled form submission'); } }); - } else { - // Log: Tidak ada email, submit form normal - console.log('No email provided, submitting form normally'); } }); }); @@ -351,7 +390,7 @@ account_number: { title: 'Account Number', render: (item, data) => { - if(data.request_type=="multi_account"){ + if (data.request_type == "multi_account") { return data.stmt_sent_type ?? 'N/A'; } return data.account_number ?? '';