feat(webstatement): dukung endPeriod dan format folder baru untuk statement

- Ubah konstruksi path SFTP dan storage lokal agar konsisten dengan format folder baru `YYYYMMDD.YYYYMMDD`
- Tambahkan dukungan periode akhir (`endPeriod`) pada alur cetak dan ekspor statement, lengkap dengan propagasi ke view dan log
- Perkuat logging di controller dan job untuk audit proses, serta sesuaikan penamaan file pada jalur PRINT

Rincian Perubahan
- PrintStatementController.php
  - Ganti path SFTP awal dari `{$period_from}/{$branch_code}/{$account_number}_{$period_from}.pdf` menjadi:
    - `{$periodPath}/PRINT/{$branch_code}/{$account_number}.1.pdf` pada cek file awal
    - Gunakan `$periodPath = formatPeriodForFolder($statement->period_from)` untuk semua referensi path
  - Iterasi ketersediaan periode:
    - Gunakan `formatPeriodForFolder($periodFormatted)` saat membentuk `periodPath` dalam loop bulan
  - Generate atau fetch statement:
    - Ubah path menjadi `{$periodPath}/{$branch_code}/{$account_number}_{$period}.pdf` untuk konsistensi
  - ZIP multi-periode:
    - Cari file ZIP pada `statements/{$periodPath}/multi_account/{$statementId}` sesuai format folder baru
  - Variabel periode:
    - Tambahkan `$endPeriod = $statement->period_to ?? $period` dan propagasikan ke:
      - Pemanggilan `generateStatementPdf($norek, $period, $endPeriod, ...)`
      - View `statements.stmt` melalui `compact(..., 'endPeriod')`
    - Perbarui logging untuk menampilkan `endPeriod`
  - Generate PDF:
    - Tandai storage path menjadi `statements/{$periodPath}/{$norek}`
    - Ubah signature: `generateStatementPdf($norek, $period, $endPeriod, ...)`
  - Akses file lokal/SFTP:
    - Ubah path storage menjadi `statements/{$periodPath}/{$account->branch_code}/{$filename}`
    - Penyesuaian delete path: `statements/{$periodPath}/{$norek}/{$filename}`

- ExportStatementPeriodJob.php
  - Tambah properti dan parameter konstruktor: `$endPeriod`
  - Ubah inisialisasi periode:
    - Ganti `calculatePeriodDates()` menjadi `formatPeriodForFolder()` (metode internal yang menetapkan `startDate` dan `endDate`)
    - Jika `$endPeriod` diisi, jadikan akhir bulan dari `endPeriod` sebagai `endDate` pemrosesan
  - Render view:
    - Tambahkan `endPeriod` ke `compact(...)` agar view mengetahui batas periode akhir
  - Storage path:
    - Gunakan `formatPeriodForFolder($this->period)` untuk path `statements/{$periodPath}/{$account->branch_code}`
  - Controller dispatch:
    - Ubah pemanggilan job menjadi `ExportStatementPeriodJob::dispatch($statementId, $accountNumber, $period, $endPeriod, $balance, $clientName)`

- resources/views/statements/stmt.blade.php
  - Periode:
    - Hitung `periodDates` via `calculatePeriodDates($period)`
    - Jika `endPeriod` ada, gunakan `calculatePeriodDates($endPeriod)` sebagai referensi `endDate`
  - Data customer:
    - Gunakan `$customer` langsung, bukan `$account->customer`
    - Kondisional alamat berdasarkan `stmt_sent_type == 'BY.MAIL.TO.DOM.ADDR'`:
      - Utamakan `l_dom_street` jika tersedia, fallback ke `address`
      - Susun RT/RW/kelurahan/kota/provinsi/kode pos sesuai preferensi pengiriman
  - Format angka:
    - Penyesuaian spasi dan casting `(float)` untuk konsistensi number_format
  - Logging:
    - Tambahkan informasi hasil perhitungan period dates untuk audit
This commit is contained in:
Daeng Deni Mardaeni
2025-11-27 18:15:33 +07:00
parent ea23401473
commit 9373325399
4 changed files with 85 additions and 41 deletions

View File

@@ -172,7 +172,11 @@ ini_set('max_execution_time', 300000);
try {
$disk = Storage::disk('sftpStatement');
$filePath = "{$statement->period_from}/{$statement->branch_code}/{$statement->account_number}_{$statement->period_from}.pdf";
// Convert period format from YYYYMM to YYYYMMDD.YYYYMMDD for folder path
$periodPath = formatPeriodForFolder($statement->period_from);
$filePath = "{$periodPath}/PRINT/{$statement->branch_code}/{$statement->account_number}.1.pdf";
// Log untuk debugging
Log::info('Checking SFTP file path', [
@@ -190,7 +194,8 @@ ini_set('max_execution_time', 300000);
for ($period = clone $periodFrom; $period->lte($periodTo); $period->addMonth()) {
$periodFormatted = $period->format('Ym');
$periodPath = $periodFormatted . "/{$statement->branch_code}/{$statement->account_number}_{$periodFormatted}.pdf";
$periodFolderPath = formatPeriodForFolder($periodFormatted);
$periodPath = $periodFolderPath . "/{$statement->branch_code}/{$statement->account_number}_{$periodFormatted}.pdf";
if ($disk->exists($periodPath)) {
$availablePeriods[] = $periodFormatted;
@@ -320,7 +325,8 @@ ini_set('max_execution_time', 300000);
// Generate or fetch the statement file
$disk = Storage::disk('sftpStatement');
$filePath = "{$statement->period_from}/{$statement->branch_code}/{$statement->account_number}_{$statement->period_from}.pdf";
$periodPath = formatPeriodForFolder($statement->period_from);
$filePath = "{$periodPath}/{$statement->branch_code}/{$statement->account_number}_{$statement->period_from}.pdf";
if ($statement->is_period_range && $statement->period_to) {
// Log: Memulai proses download period range
@@ -343,7 +349,8 @@ ini_set('max_execution_time', 300000);
for ($period = clone $periodFrom; $period->lte($periodTo); $period->addMonth()) {
$periodFormatted = $period->format('Ym');
$periodPath = $periodFormatted . "/{$statement->branch_code}/{$statement->account_number}_{$periodFormatted}.pdf";
$periodFolderPath = formatPeriodForFolder($periodFormatted);
$periodPath = $periodFolderPath . "/{$statement->branch_code}/{$statement->account_number}_{$periodFormatted}.pdf";
if ($disk->exists($periodPath)) {
$availablePeriods[] = $periodFormatted;
@@ -387,7 +394,8 @@ ini_set('max_execution_time', 300000);
// Add each available statement to the zip
foreach ($availablePeriods as $period) {
$periodFilePath = "{$period}/{$statement->branch_code}/{$statement->account_number}_{$period}.pdf";
$periodFolderPath = formatPeriodForFolder($period);
$periodFilePath = "{$periodFolderPath}/{$statement->branch_code}/{$statement->account_number}_{$period}.pdf";
$localFilePath = storage_path("app/temp/{$statement->account_number}_{$period}.pdf");
try {
@@ -672,7 +680,8 @@ ini_set('max_execution_time', 300000);
$localDisk = Storage::disk('local');
$sftpDisk = Storage::disk('sftpStatement');
$filePath = "{$statement->period_from}/{$statement->branch_code}/{$statement->account_number}_{$statement->period_from}.pdf";
$periodPath = formatPeriodForFolder($statement->period_from);
$filePath = "{$periodPath}/{$statement->branch_code}/{$statement->account_number}_{$statement->period_from}.pdf";
/**
* Fungsi helper untuk mendapatkan file dari disk dengan prioritas local
@@ -722,7 +731,8 @@ ini_set('max_execution_time', 300000);
for ($period = clone $periodFrom; $period->lte($periodTo); $period->addMonth()) {
$periodFormatted = $period->format('Ym');
$periodPath = "{$periodFormatted}/{$statement->branch_code}/{$statement->account_number}_{$periodFormatted}.pdf";
$periodFolderPath = formatPeriodForFolder($periodFormatted);
$periodPath = "{$periodFolderPath}/{$statement->branch_code}/{$statement->account_number}_{$periodFormatted}.pdf";
$fileInfo = $getFileFromDisk($periodPath);
@@ -910,6 +920,7 @@ ini_set('max_execution_time', 300000);
$norek = $statement->account_number;
$period = $statement->period_from;
$endPeriod = $statement->period_to ?? $period;
$format='pdf';
// Generate nama file PDF
@@ -981,20 +992,21 @@ ini_set('max_execution_time', 300000);
Log::info('Statement data prepared successfully', [
'account_number' => $norek,
'period' => $period,
'endPeriod' => $endPeriod ?? $period,
'saldo_period' => $saldoPeriod,
'saldo_awal' => $saldoAwalBulan->actual_balance ?? 0,
'entries_count' => $stmtEntries->count()
]);
$periodDates = calculatePeriodDates($period);
$periodDates = formatPeriodForFolder($period);
// Jika format adalah PDF, generate PDF
if ($format === 'pdf') {
return $this->generateStatementPdf($norek, $period, $stmtEntries, $account, $customer, $headerTableBg, $branch, $saldoAwalBulan, $statement->id, $tempPath, $filename);
return $this->generateStatementPdf($norek, $period, $endPeriod, $stmtEntries, $account, $customer, $headerTableBg, $branch, $saldoAwalBulan, $statement->id, $tempPath, $filename);
}
// Default return HTML view
return view('webstatement::statements.stmt', compact('stmtEntries', 'account', 'customer', 'headerTableBg', 'branch', 'period', 'saldoAwalBulan'));
return view('webstatement::statements.stmt', compact('stmtEntries', 'account', 'customer', 'headerTableBg', 'branch', 'period', 'saldoAwalBulan', 'endPeriod'));
} catch (Exception $e) {
DB::rollBack();
@@ -1032,7 +1044,7 @@ ini_set('max_execution_time', 300000);
* @param object $saldoAwalBulan Data saldo awal
* @return \Illuminate\Http\Response
*/
protected function generateStatementPdf($norek, $period, $stmtEntries, $account, $customer, $headerTableBg, $branch, $saldoAwalBulan, $statementId, $tempPath, $filename)
protected function generateStatementPdf($norek, $period, $endPeriod, $stmtEntries, $account, $customer, $headerTableBg, $branch, $saldoAwalBulan, $statementId, $tempPath, $filename)
{
try {
DB::beginTransaction();
@@ -1040,6 +1052,7 @@ ini_set('max_execution_time', 300000);
Log::info('Starting PDF generation with storage', [
'account_number' => $norek,
'period' => $period,
'endPeriod' => $endPeriod ?? $period,
'user_id' => Auth::id()
]);
@@ -1051,10 +1064,12 @@ ini_set('max_execution_time', 300000);
'headerTableBg',
'branch',
'period',
'endPeriod',
'saldoAwalBulan'
))->render();
// Tentukan path storage
$storagePath = "statements/{$period}/{$norek}";
// Tentukan path storage dengan format folder baru
$periodPath = formatPeriodForFolder($period);
$storagePath = "statements/{$periodPath}/{$norek}";
$fullStoragePath = "{$storagePath}/{$filename}";
// Generate PDF menggunakan Browsershot dan simpan langsung ke storage
@@ -1230,7 +1245,8 @@ ini_set('max_execution_time', 300000);
$account = Account::where('account_number',$norek)->first();
$storagePath = "statements/{$period}/{$account->branch_code}/{$filename}";
$periodPath = formatPeriodForFolder($period);
$storagePath = "statements/{$periodPath}/{$account->branch_code}/{$filename}";
// Cek apakah file ada di storage
if (!Storage::disk('local')->exists($storagePath)) {
@@ -1289,7 +1305,8 @@ ini_set('max_execution_time', 300000);
$filename = $this->generatePdfFileName($norek, $period);
}
$storagePath = "statements/{$period}/{$norek}/{$filename}";
$periodPath = formatPeriodForFolder($period);
$storagePath = "statements/{$periodPath}/{$norek}/{$filename}";
if (Storage::disk('local')->exists($storagePath)) {
$deleted = Storage::disk('local')->delete($storagePath);
@@ -1523,6 +1540,8 @@ ini_set('max_execution_time', 300000);
$accountNumber = $statement->account_number;
$period = $statement->period_from ?? date('Ym');
$endPeriod = $statement->period_to ?? $period;
$balance = AccountBalance::where('account_number', $accountNumber)
->when($period === '202505', function($query) {
return $query->where('period', '>=', '20250512')
@@ -1546,7 +1565,7 @@ ini_set('max_execution_time', 300000);
}
// Dispatch the job
$job = ExportStatementPeriodJob::dispatch($statement->id, $accountNumber, $period, $balance, $clientName);
$job = ExportStatementPeriodJob::dispatch($statement->id, $accountNumber, $period, $endPeriod, $balance, $clientName);
Log::info("Statement export job dispatched successfully", [
'job_id' => $job->job_id ?? null,
@@ -1606,8 +1625,9 @@ ini_set('max_execution_time', 300000);
], 404);
}
// Find ZIP file
$zipFiles = Storage::disk('local')->files("statements/{$statement->period_from}/multi_account/{$statementId}");
// Find ZIP file dengan format folder baru
$periodPath = formatPeriodForFolder($statement->period_from);
$zipFiles = Storage::disk('local')->files("statements/{$periodPath}/multi_account/{$statementId}");
$zipFile = null;
foreach ($zipFiles as $file) {