feat(webstatement): tambahkan fitur pengiriman email statement PDF
- Menambahkan Command `SendStatementEmailCommand` untuk mengirim email statement PDF: - Mendukung parameter input seperti periode laporan (`YYYY-MM`), nomor rekening, ID batch, queue, dan delay waktu. - Menjalankan validasi parameter input, mencatat log eksekusi, dan mendispatch job pengiriman email. - Menyediakan feedback status eksekusi serta informasi job kepada user. - Menambahkan Job `SendStatementEmailJob` untuk pengiriman statement dalam latar belakang: - Memfilter account yang memiliki email terkait, baik dari `stmt_email` atau email dari data customer. - Melakukan pengiriman email dengan attachment file PDF statement. - Mencatat log sukses atau kegagalan pengiriman untuk setiap account. - Memperbarui Model dan Template Email: - Mengubah template email untuk mendukung pengisian nama rekening secara dinamis berdasarkan customer account. - Menambahkan pengisian dinamis untuk tahun copyright di footer. - Memperbarui Provider `WebstatementServiceProvider`: - Mendaftarkan Command baru `SendStatementEmailCommand` ke dalam aplikasi. Signed-off-by: Daeng Deni Mardaeni <ddeni05@gmail.com>
This commit is contained in:
191
app/Console/SendStatementEmailCommand.php
Normal file
191
app/Console/SendStatementEmailCommand.php
Normal file
@@ -0,0 +1,191 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Webstatement\Console;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Modules\Webstatement\Jobs\SendStatementEmailJob;
|
||||
use Modules\Webstatement\Models\Account;
|
||||
|
||||
/**
|
||||
* Command untuk mengirim email statement PDF ke nasabah
|
||||
*
|
||||
* Command ini akan:
|
||||
* 1. Memvalidasi parameter input
|
||||
* 2. Menjalankan job pengiriman email statement
|
||||
* 3. Memberikan feedback ke user tentang status eksekusi
|
||||
*/
|
||||
class SendStatementEmailCommand extends Command
|
||||
{
|
||||
/**
|
||||
* Signature dan parameter command
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'webstatement:send-email
|
||||
{period : Format periode YYYY-MM (contoh: 2024-01)}
|
||||
{--account= : Nomor rekening spesifik (opsional)}
|
||||
{--batch-id= : ID batch untuk tracking (opsional)}
|
||||
{--queue=emails : Nama queue untuk job (default: emails)}
|
||||
{--delay=0 : Delay dalam menit sebelum job dijalankan}';
|
||||
|
||||
/**
|
||||
* Deskripsi command
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Mengirim email statement PDF ke nasabah berdasarkan periode';
|
||||
|
||||
/**
|
||||
* Menjalankan command
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->info('🚀 Memulai proses pengiriman email statement...');
|
||||
|
||||
try {
|
||||
// Ambil parameter
|
||||
$period = $this->argument('period');
|
||||
$accountNumber = $this->option('account');
|
||||
$batchId = $this->option('batch-id');
|
||||
$queueName = $this->option('queue');
|
||||
$delay = (int) $this->option('delay');
|
||||
|
||||
// Validasi parameter
|
||||
if (!$this->validateParameters($period, $accountNumber)) {
|
||||
return Command::FAILURE;
|
||||
}
|
||||
|
||||
// Log command execution
|
||||
Log::info('SendStatementEmailCommand started', [
|
||||
'period' => $period,
|
||||
'account_number' => $accountNumber,
|
||||
'batch_id' => $batchId,
|
||||
'queue' => $queueName,
|
||||
'delay' => $delay
|
||||
]);
|
||||
|
||||
// Dispatch job
|
||||
$job = SendStatementEmailJob::dispatch($period, $accountNumber, $batchId)
|
||||
->onQueue($queueName);
|
||||
|
||||
if ($delay > 0) {
|
||||
$job->delay(now()->addMinutes($delay));
|
||||
$this->info("⏰ Job dijadwalkan untuk dijalankan dalam {$delay} menit");
|
||||
}
|
||||
|
||||
// Tampilkan informasi
|
||||
$this->displayJobInfo($period, $accountNumber, $batchId, $queueName);
|
||||
|
||||
$this->info('✅ Job pengiriman email statement berhasil didispatch!');
|
||||
$this->info('📊 Gunakan command berikut untuk monitoring:');
|
||||
$this->line(" php artisan queue:work {$queueName}");
|
||||
$this->line(' php artisan telescope:work (jika menggunakan Telescope)');
|
||||
|
||||
return Command::SUCCESS;
|
||||
|
||||
} catch (Exception $e) {
|
||||
$this->error('❌ Error saat mendispatch job: ' . $e->getMessage());
|
||||
|
||||
Log::error('SendStatementEmailCommand failed', [
|
||||
'error' => $e->getMessage(),
|
||||
'trace' => $e->getTraceAsString()
|
||||
]);
|
||||
|
||||
return Command::FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validasi parameter input
|
||||
*
|
||||
* @param string $period
|
||||
* @param string|null $accountNumber
|
||||
* @return bool
|
||||
*/
|
||||
private function validateParameters($period, $accountNumber = null)
|
||||
{
|
||||
// Validasi format periode
|
||||
if (!preg_match('/^\d{4}\d{2}$/', $period)) {
|
||||
$this->error('❌ Format periode tidak valid. Gunakan format YYYYMM (contoh: 202401)');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validasi account number jika diberikan
|
||||
if ($accountNumber) {
|
||||
$account = Account::with('customer')
|
||||
->where('account_number', $accountNumber)
|
||||
->first();
|
||||
|
||||
if (!$account) {
|
||||
$this->error("❌ Account {$accountNumber} tidak ditemukan");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cek apakah ada email (dari stmt_email atau customer email)
|
||||
$hasEmail = !empty($account->stmt_email) ||
|
||||
($account->customer && !empty($account->customer->email));
|
||||
|
||||
if (!$hasEmail) {
|
||||
$this->error("❌ Account {$accountNumber} tidak memiliki email (baik di stmt_email maupun customer email)");
|
||||
return false;
|
||||
}
|
||||
|
||||
$emailSource = !empty($account->stmt_email) ? 'stmt_email' : 'customer email';
|
||||
$emailAddress = !empty($account->stmt_email) ? $account->stmt_email : $account->customer->email;
|
||||
|
||||
$this->info("✅ Account {$accountNumber} ditemukan dengan email: {$emailAddress} (dari {$emailSource}) - Cabang: {$account->branch_code}");
|
||||
} else {
|
||||
// Cek apakah ada account dengan email (dari stmt_email atau customer email)
|
||||
$accountCount = Account::with('customer')
|
||||
->where('stmt_sent_type', 'BY.EMAIL')
|
||||
->get()
|
||||
->filter(function ($account) {
|
||||
return !empty($account->stmt_email) ||
|
||||
($account->customer && !empty($account->customer->email));
|
||||
})
|
||||
->count();
|
||||
|
||||
if ($accountCount === 0) {
|
||||
$this->error('❌ Tidak ada account dengan email ditemukan (baik di stmt_email maupun customer email)');
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->info("✅ Ditemukan {$accountCount} account dengan email");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Menampilkan informasi job yang akan dijalankan
|
||||
*
|
||||
* @param string $period
|
||||
* @param string|null $accountNumber
|
||||
* @param string|null $batchId
|
||||
* @param string $queueName
|
||||
* @return void
|
||||
*/
|
||||
private function displayJobInfo($period, $accountNumber, $batchId, $queueName)
|
||||
{
|
||||
$this->info('📋 Detail Job:');
|
||||
$this->line(" Periode: {$period}");
|
||||
$this->line(" Account: " . ($accountNumber ?: 'Semua account dengan email'));
|
||||
$this->line(" Batch ID: " . ($batchId ?: 'Auto-generated'));
|
||||
$this->line(" Queue: {$queueName}");
|
||||
|
||||
// Estimasi path file
|
||||
if ($accountNumber) {
|
||||
$account = Account::where('account_number', $accountNumber)->first();
|
||||
if ($account) {
|
||||
$pdfPath = "storage/app/combine/{$period}/{$account->branch_code}/{$accountNumber}_{$period}.pdf";
|
||||
$this->line(" File PDF: {$pdfPath}");
|
||||
}
|
||||
} else {
|
||||
$this->line(" File PDF: storage/app/combine/{$period}/[branch_code]/[account_number]_{$period}.pdf");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user