feat(webstatement): tambah console command dan perbaikan field required untuk laporan closing balance

Menambahkan fitur command line untuk generate laporan closing balance sekaligus memperbaiki pengisian field yang required di database.

Perubahan yang dilakukan:
- Membuat command `webstatement:generate-closing-balance-report` dengan parameter:
  - `account_number`: nomor rekening (required)
  - `period`: format tanggal YYYYMMDD (required)
  - `--user_id=`: ID user (optional, default 1)
- Menambahkan field `report_date` dengan konversi dari parameter `period` menggunakan Carbon
- Menambahkan field `created_by` dan `updated_by` untuk kebutuhan audit trail
- Menambahkan field `ip_address` dan `user_agent` dengan default 'console' untuk identifikasi proses non-web
- Memperbaiki validasi parameter dengan regex dan proper escaping
- Menghindari error SQLSTATE[23502] terkait field not null di database schema
- Menggunakan database transaction untuk menjaga konsistensi data
- Mengupdate fungsi `closing_balance_report_logs` untuk menyimpan semua field yang dibutuhkan
- Integrasi dengan `GenerateClosingBalanceReportJob` untuk pemrosesan laporan secara background
- Menambahkan logging komprehensif untuk monitoring `report_date` dan proses lainnya
- Mendukung eksekusi manual dan penjadwalan via Laravel scheduler
- Kompatibel dengan proses laporan closing balance via web dan CLI

Tujuan perubahan:
- Mempermudah proses generate laporan closing balance melalui CLI secara manual atau terjadwal
- Memastikan seluruh field wajib di `closing_balance_report_logs` terisi dengan benar
- Menyediakan audit trail lengkap dan logging yang detail untuk proses via console
- Meningkatkan keandalan sistem dengan validasi dan error handling yang lebih baik
This commit is contained in:
Daeng Deni Mardaeni
2025-07-17 21:42:11 +07:00
parent 3beaf78872
commit 3c01c1728c
5 changed files with 250 additions and 20 deletions

View File

@@ -0,0 +1,211 @@
<?php
namespace Modules\Webstatement\Console;
use Exception;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Modules\Usermanagement\Models\User;
use Modules\Webstatement\Jobs\GenerateClosingBalanceReportJob;
use Modules\Webstatement\Models\ClosingBalanceReportLog;
use Carbon\Carbon;
/**
* Console command untuk generate laporan closing balance
* Command ini dapat dijalankan secara manual atau dijadwalkan
*/
class GenerateClosingBalanceReportCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'webstatement:generate-closing-balance-report
{account_number : Nomor rekening untuk generate laporan}
{period : Period laporan format YYYYMMDD, contoh: 20250515}
{--user_id=1 : ID user yang menjalankan command (default: 1)}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Generate Closing Balance report untuk nomor rekening dan periode tertentu';
/**
* Execute the console command.
* Menjalankan proses generate laporan closing balance
*
* @return int
*/
public function handle()
{
$this->info('Starting Closing Balance report generation...');
// Get parameters
$accountNumber = $this->argument('account_number');
$period = $this->argument('period');
$userId = $this->option('user_id');
// Validate parameters
if (!$this->validateParameters($accountNumber, $period, $userId)) {
return Command::FAILURE;
}
try {
DB::beginTransaction();
// Log start of process
Log::info('Console command: Starting closing balance report generation', [
'account_number' => $accountNumber,
'period' => $period,
'user_id' => $userId,
'command' => 'webstatement:generate-closing-balance-report'
]);
// Create report log entry
$reportLog = $this->createReportLog($accountNumber, $period, $userId);
if (!$reportLog) {
$this->error('Failed to create report log entry');
DB::rollback();
return Command::FAILURE;
}
// Dispatch the job
GenerateClosingBalanceReportJob::dispatch($accountNumber, $period, $reportLog->id);
DB::commit();
$this->info("Closing Balance report generation job queued successfully!");
$this->info("Account Number: {$accountNumber}");
$this->info("Period: {$period}");
$this->info("Report Log ID: {$reportLog->id}");
$this->info('The report will be generated in the background.');
$this->info('Check the closing_balance_report_logs table for progress.');
// Log successful dispatch
Log::info('Console command: Closing balance report job dispatched successfully', [
'account_number' => $accountNumber,
'period' => $period,
'report_log_id' => $reportLog->id,
'user_id' => $userId
]);
return Command::SUCCESS;
} catch (Exception $e) {
DB::rollback();
$this->error('Error queuing Closing Balance report job: ' . $e->getMessage());
// Log error
Log::error('Console command: Error generating closing balance report', [
'account_number' => $accountNumber,
'period' => $period,
'user_id' => $userId,
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
return Command::FAILURE;
}
}
/**
* Validate command parameters
* Validasi parameter command
*
* @param string $accountNumber
* @param string $period
* @param int $userId
* @return bool
*/
private function validateParameters(string $accountNumber, string $period, int $userId): bool
{
// Validate account number
if (empty($accountNumber)) {
$this->error('Account number parameter is required.');
return false;
}
// Validate period format (YYYYMMDD)
if (!preg_match('/^\\d{8}$/', $period)) {
$this->error('Invalid period format. Use YYYYMMDD format (example: 20250515)');
return false;
}
// Validate date
$year = substr($period, 0, 4);
$month = substr($period, 4, 2);
$day = substr($period, 6, 2);
if (!checkdate($month, $day, $year)) {
$this->error('Invalid date in period parameter.');
return false;
}
// Validate user exists
$user = User::find($userId);
if (!$user) {
$this->error("User with ID {$userId} not found.");
return false;
}
return true;
}
/**
* Create report log entry
* Membuat entry log laporan
*
* @param string $accountNumber
* @param string $period
* @param int $userId
* @return ClosingBalanceReportLog|null
*/
private function createReportLog(string $accountNumber, string $period, int $userId): ?ClosingBalanceReportLog
{
try {
// Convert period string to Carbon date
$reportDate = Carbon::createFromFormat('Ymd', $period);
$reportLog = ClosingBalanceReportLog::create([
'account_number' => $accountNumber,
'period' => $period,
'report_date' => $reportDate, // Required field yang sebelumnya missing
'status' => 'pending',
'user_id' => $userId,
'created_by' => $userId, // Required field yang sebelumnya missing
'updated_by' => $userId,
'ip_address' => request()->ip() ?? '127.0.0.1', // Default untuk console
'user_agent' => 'Console Command',
'created_at' => now(),
'updated_at' => now()
]);
Log::info('Console command: Report log created', [
'report_log_id' => $reportLog->id,
'account_number' => $accountNumber,
'period' => $period,
'report_date' => $reportDate->format('Y-m-d'),
'user_id' => $userId
]);
return $reportLog;
} catch (Exception $e) {
Log::error('Console command: Error creating report log', [
'account_number' => $accountNumber,
'period' => $period,
'user_id' => $userId,
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
return null;
}
}
}

View File

@@ -29,7 +29,7 @@ class LaporanClosingBalanceController extends Controller
public function index()
{
Log::info('Mengakses halaman laporan closing balance');
return view('webstatement::closing-balance-reports.index');
return view('webstatement::laporan-closing-balance.index');
}
/**
@@ -92,7 +92,7 @@ class LaporanClosingBalanceController extends Controller
'period' => $period
]);
return redirect()->route('closing-balance-reports.index')
return redirect()->route('laporan-closing-balance.index')
->with('success', 'Permintaan laporan closing balance berhasil dibuat dan sedang diproses.');
} catch (Exception $e) {
@@ -117,7 +117,7 @@ class LaporanClosingBalanceController extends Controller
public function create()
{
Log::info('Menampilkan form pembuatan laporan closing balance');
return view('webstatement::closing-balance-reports.create');
return view('webstatement::laporan-closing-balance.create');
}
/**
@@ -133,7 +133,7 @@ class LaporanClosingBalanceController extends Controller
]);
$closingBalanceReport->load(['user', 'creator', 'authorizer']);
return view('webstatement::closing-balance-reports.show', compact('closingBalanceReport'));
return view('webstatement::laporan-closing-balance.show', compact('closingBalanceReport'));
}
/**
@@ -242,7 +242,7 @@ class LaporanClosingBalanceController extends Controller
'status' => $request->authorization_status
]);
return redirect()->route('closing-balance-reports.show', $closingBalanceReport->id)
return redirect()->route('laporan-closing-balance.show', $closingBalanceReport->id)
->with('success', "Permintaan laporan closing balance berhasil {$statusText}.");
} catch (Exception $e) {

View File

@@ -130,8 +130,13 @@ class GenerateClosingBalanceReportJob implements ShouldQueue
'period' => $this->period
]);
// Get previous period based on current period
$previousPeriod = $this->period === '20250512'
? Carbon::createFromFormat('Ymd', $this->period)->subDays(2)->format('Ymd')
: Carbon::createFromFormat('Ymd', $this->period)->subDay()->format('Ymd');
$accountBalance = AccountBalance::where('account_number', $this->accountNumber)
->where('period', $this->period)
->where('period', $previousPeriod)
->first();
if (!$accountBalance) {

View File

@@ -6,20 +6,23 @@ use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
use Nwidart\Modules\Traits\PathNamespace;
use Illuminate\Console\Scheduling\Schedule;
use Modules\Webstatement\Console\UnlockPdf;
use Modules\Webstatement\Console\CombinePdf;
use Modules\Webstatement\Console\ConvertHtmlToPdf;
use Modules\Webstatement\Console\ExportDailyStatements;
use Modules\Webstatement\Console\ProcessDailyMigration;
use Modules\Webstatement\Console\ExportPeriodStatements;
use Modules\Webstatement\Console\UpdateAllAtmCardsCommand;
use Modules\Webstatement\Console\CheckEmailProgressCommand;
use Modules\Webstatement\Console\AutoSendStatementEmailCommand;
use Modules\Webstatement\Console\GenerateBiayakartuCommand;
use Modules\Webstatement\Console\SendStatementEmailCommand;
use Modules\Webstatement\Console\{
UnlockPdf,
CombinePdf,
ConvertHtmlToPdf,
ExportDailyStatements,
ProcessDailyMigration,
ExportPeriodStatements,
UpdateAllAtmCardsCommand,
CheckEmailProgressCommand,
GenerateBiayakartuCommand,
SendStatementEmailCommand,
GenerateAtmTransactionReport,
GenerateBiayaKartuCsvCommand,
AutoSendStatementEmailCommand,
GenerateClosingBalanceReportCommand
};
use Modules\Webstatement\Jobs\UpdateAtmCardBranchCurrencyJob;
use Modules\Webstatement\Console\GenerateAtmTransactionReport;
use Modules\Webstatement\Console\GenerateBiayaKartuCsvCommand;
class WebstatementServiceProvider extends ServiceProvider
{
@@ -74,7 +77,8 @@ class WebstatementServiceProvider extends ServiceProvider
SendStatementEmailCommand::class,
CheckEmailProgressCommand::class,
UpdateAllAtmCardsCommand::class,
AutoSendStatementEmailCommand::class
AutoSendStatementEmailCommand::class,
GenerateClosingBalanceReportCommand::class,
]);
}

View File

@@ -77,6 +77,16 @@
"roles": [
"administrator"
]
},{
"title": "Laporan Closing Balance",
"path": "laporan-closing-balance",
"icon": "ki-filled ki-printer text-lg text-primary",
"classes": "",
"attributes": [],
"permission": "",
"roles": [
"administrator"
]
}
],
"master": [