From df5d0c420b2f84591ccfe804c3ef03b07eef3f61 Mon Sep 17 00:00:00 2001 From: Daeng Deni Mardaeni Date: Thu, 5 Jun 2025 11:19:25 +0700 Subject: [PATCH] feat(webstatement): optimalkan logika combine PDF dan pengaturan password dinamis - Memperbarui fungsi `combinePdfs` di `CombinePdfController`: - Menambahkan dukungan pengunduhan file `r23` dari SFTP dan penyimpanan sementara ke direktori lokal. - Mengubah filter `branch_code` dari `ID0010001` menjadi `ID0010052` untuk pemrosesan akun. - Menambahkan log peringatan dan error untuk mengelola skenario file yang tidak ditemukan atau error saat unduhan dari SFTP. - Memperkenalkan logika baru untuk pengaturan password dinamis pada file PDF: - Menambahkan metode `generatePassword` untuk menghasilkan password berdasarkan data customers. - Format password: kombinasi `ddMmmyyyyXX` (contoh: 05Oct202585), menggunakan tanggal yang relevan dan 2 digit terakhir nomor rekening. - Handling fallback ke nomor rekening jika tidak ada data tanggal yang tersedia. - Menambahkan validasi parsing tanggal untuk menghindari error format. - Tujuan pembaruan ini: - Memastikan proses combine PDF lebih fleksibel dengan pengunduhan file dari SFTP. - Meningkatkan keamanan PDF dengan pengaturan password dinamis berdasarkan data customers. - Mempermudah troubleshooting dengan penambahan log yang lebih informatif terkait proses file dan password. Signed-off-by: Daeng Deni Mardaeni --- app/Http/Controllers/CombinePdfController.php | 115 +++++++++++++++--- 1 file changed, 95 insertions(+), 20 deletions(-) diff --git a/app/Http/Controllers/CombinePdfController.php b/app/Http/Controllers/CombinePdfController.php index f05eebe..30a67e6 100644 --- a/app/Http/Controllers/CombinePdfController.php +++ b/app/Http/Controllers/CombinePdfController.php @@ -5,9 +5,11 @@ namespace Modules\Webstatement\Http\Controllers; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Illuminate\Support\Facades\File; +use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Log; use Modules\Webstatement\Jobs\CombinePdfJob; use Modules\Webstatement\Models\Account; +use Carbon\Carbon; class CombinePdfController extends Controller { @@ -30,8 +32,8 @@ class CombinePdfController extends Controller // Get period from request or use current period $period = $period ?? date('Ym'); - // Get all accounts - $accounts = Account::where('branch_code','ID0010001')->get(); + // Get all accounts with customer relation + $accounts = Account::where('branch_code','ID0010052')->get(); $processedCount = 0; $skippedCount = 0; $errorCount = 0; @@ -40,42 +42,61 @@ class CombinePdfController extends Controller $branchCode = $account->branch_code; $accountNumber = $account->account_number; - // Define file paths - $r14Path = storage_path("app/STMT/r14/{$period}/{$branchCode}/{$accountNumber}_{$period}.pdf"); - $r23Path = storage_path("app/STMT/r23/{$period}/{$branchCode}/{$accountNumber}_{$period}.pdf"); + // Define file paths - r14 from local, r23 from SFTP + $r14Path = storage_path("app/r14/{$accountNumber}_{$period}.pdf"); + $r23SftpPath = "r23/{$accountNumber}.1.pdf"; + + // Define local temporary path for r23 file downloaded from SFTP + $tempDir = storage_path("app/temp/{$period}"); + if (!File::exists($tempDir)) { + File::makeDirectory($tempDir, 0755, true); + } + $r23LocalPath = "{$tempDir}/{$accountNumber}_r23.pdf"; + $outputDir = storage_path("app/combine/{$period}/{$branchCode}"); $outputFilename = "{$accountNumber}_{$period}.pdf"; - // Check if files exist + // Check if r14 file exists locally $r14Exists = File::exists($r14Path); - $r23Exists = File::exists($r23Path); + + // Check if r23 file exists on SFTP and download it + $r23Exists = false; + try { + if (Storage::disk('sftpStatement')->exists($r23SftpPath)) { + $r23Content = Storage::disk('sftpStatement')->get($r23SftpPath); + File::put($r23LocalPath, $r23Content); + $r23Exists = true; + Log::info("Downloaded r23 file for account {$accountNumber} from SFTP"); + } + } catch (\Exception $e) { + Log::error("Error downloading r23 file from SFTP for account {$accountNumber}: {$e->getMessage()}"); + } // Skip if neither file exists if (!$r14Exists && !$r23Exists) { - Log::warning("No PDF files found for account {$accountNumber}"); + //Log::warning("No PDF files found for account {$accountNumber}"); $skippedCount++; continue; } - // If both files exist, combine them - if ($r14Exists && $r23Exists) { - Log::info("Combining PDFs for account {$accountNumber}"); - $pdfFiles = [$r14Path, $r23Path]; + // Prepare file list for processing + $pdfFiles = []; + if ($r14Exists) { + $pdfFiles[] = $r14Path; } - // If only one file exists, just apply password protection - else { - Log::info("Applying password protection to single PDF for account {$accountNumber}"); - $pdfFile = $r14Exists ? $r14Path : $r23Path; - $pdfFiles = [$pdfFile]; + if ($r23Exists) { + $pdfFiles[] = $r23LocalPath; } try { - // Use the account number as password - $password = $accountNumber; + // Generate password based on customer relation data + $password = $this->generatePassword($account); // Dispatch job to combine PDFs or apply password protection CombinePdfJob::dispatch($pdfFiles, $outputDir, $outputFilename, $password); $processedCount++; + + Log::info("Queued PDF processing for account {$accountNumber} - r14: local, r23: SFTP, password: {$password}"); } catch (\Exception $e) { Log::error("Error processing PDF for account {$accountNumber}: {$e->getMessage()}"); $errorCount++; @@ -83,11 +104,65 @@ class CombinePdfController extends Controller } return response()->json([ - 'message' => 'PDF combination process has been queued', + 'message' => 'PDF combination process has been queued (r14: local, r23: SFTP)', 'processed' => $processedCount, 'skipped' => $skippedCount, 'errors' => $errorCount, 'period' => $period ]); } + + /** + * Generate password based on customer relation data + * Format: date+end 2 digit account_number + * Example: 05Oct202585 + * + * @param Account $account + * @return string + */ + private function generatePassword(Account $account) + { + $customer = $account->customer; + $accountNumber = $account->account_number; + + // Get last 2 digits of account number + $lastTwoDigits = substr($accountNumber, -2); + + // Determine which date to use based on sector + $dateToUse = null; + + if ($customer && $customer->sector) { + $firstDigitSector = substr($customer->sector, 0, 1); + + if ($firstDigitSector === '1') { + // Use date_of_birth if available, otherwise birth_incorp_date + $dateToUse = $customer->date_of_birth ?: $customer->birth_incorp_date; + } else { + // Use birth_incorp_date for sector > 1 + $dateToUse = $customer->birth_incorp_date; + } + } + + // If no date found, fallback to account number + if (!$dateToUse) { + Log::warning("No date found for account {$accountNumber}, using account number as password"); + return $accountNumber; + } + + try { + // Parse the date and format it + $date = Carbon::parse($dateToUse); + $day = $date->format('d'); + $month = $date->format('M'); // 3-letter month abbreviation + $year = $date->format('Y'); + + // Format: ddMmmyyyyXX (e.g., 05Oct202585) + $password = $day . $month . $year . $lastTwoDigits; + + return $password; + } catch (\Exception $e) { + Log::error("Error parsing date for account {$accountNumber}: {$e->getMessage()}"); + return $accountNumber; // Fallback to account number + } + } }