feat(webstatement): tingkatkan proses pengiriman email dengan PHPMailer
- **Migrasi ke PHPMailer:** - Mengganti penggunaan `Illuminate\Support\Facades\Mail` ke PHPMailer untuk pengiriman email. - Menambahkan service baru `PHPMailerService` dengan dukungan autentikasi NTLM/GSSAPI. - Mengintegrasikan logika pengiriman email ke dalam `StatementEmail` menggunakan PHPMailer. - Memindahkan logika attachment dan body email ke helper method pada kelas `StatementEmail`. - **Perbaikan Logging dan Penanganan Error:** - Menambah logging lebih mendetail pada proses pengiriman email, termasuk informasi seperti penerima, subjek, dan status pengiriman. - Menambahkan fallback untuk pembuatan konten HTML jika terjadi kegagalan rendering pada template Blade. - Menambahkan pengecekan dan logging untuk kegagalan pengiriman email dengan mekanisme exception handling. - **Peningkatan Template Email:** - Memperbaiki elemen ulasan pada template email untuk mendukung tampilan yang lebih bersih menggunakan `list-style-type: none`. - Memodifikasi markup footer untuk memberikan batas terformat lebih baik. - **Optimasi Proses Backend:** - Menambahkan delay antar pengiriman email untuk menghindari rate limiting pada koneksi NTLM/GSSAPI. - Menyediakan format nama attachment dinamis berdasarkan rekening dan periode laporan. - Memanfaatkan konfigurasi enkripsi dinamis, dengan fallback untuk pengujian/development. Signed-off-by: Daeng Deni Mardaeni <ddeni05@gmail.com>
This commit is contained in:
@@ -2,19 +2,22 @@
|
||||
|
||||
namespace Modules\Webstatement\Mail;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Modules\Webstatement\Models\Account;
|
||||
use Modules\Webstatement\Models\PrintStatementLog;
|
||||
use Modules\Webstatement\Services\PHPMailerService;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\View;
|
||||
|
||||
class StatementEmail extends Mailable
|
||||
/**
|
||||
* Service untuk mengirim email statement menggunakan PHPMailer
|
||||
* dengan dukungan autentikasi NTLM/GSSAPI
|
||||
*/
|
||||
class StatementEmail
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
protected $statement;
|
||||
protected $filePath;
|
||||
protected $isZip;
|
||||
protected $phpMailerService;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
@@ -29,15 +32,69 @@ class StatementEmail extends Mailable
|
||||
$this->statement = $statement;
|
||||
$this->filePath = $filePath;
|
||||
$this->isZip = $isZip;
|
||||
$this->phpMailerService = new PHPMailerService();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the message.
|
||||
* Membangun struktur email dengan attachment statement
|
||||
* Kirim email statement
|
||||
*
|
||||
* @return $this
|
||||
* @param string $emailAddress
|
||||
* @return bool
|
||||
*/
|
||||
public function build()
|
||||
public function send(string $emailAddress): bool
|
||||
{
|
||||
try {
|
||||
// Generate subject
|
||||
$subject = $this->generateSubject();
|
||||
|
||||
// Generate email body
|
||||
$body = $this->generateEmailBody();
|
||||
|
||||
// Generate attachment name
|
||||
$attachmentName = $this->generateAttachmentName();
|
||||
|
||||
// Determine MIME type
|
||||
$mimeType = $this->isZip ? 'application/zip' : 'application/pdf';
|
||||
|
||||
// Send email using PHPMailer
|
||||
$result = $this->phpMailerService->sendEmail(
|
||||
$emailAddress,
|
||||
$subject,
|
||||
$body,
|
||||
$this->filePath,
|
||||
$attachmentName,
|
||||
$mimeType
|
||||
);
|
||||
|
||||
Log::info('Statement email sent via PHPMailer', [
|
||||
'to' => $emailAddress,
|
||||
'subject' => $subject,
|
||||
'attachment' => $attachmentName,
|
||||
'account_number' => $this->statement->account_number,
|
||||
'period' => $this->statement->period_from,
|
||||
'success' => $result
|
||||
]);
|
||||
|
||||
return $result;
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Failed to send statement email via PHPMailer', [
|
||||
'to' => $emailAddress,
|
||||
'account_number' => $this->statement->account_number,
|
||||
'error' => $e->getMessage(),
|
||||
'trace' => $e->getTraceAsString()
|
||||
]);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate email subject
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function generateSubject(): string
|
||||
{
|
||||
$subject = 'Statement Rekening Bank Artha Graha Internasional';
|
||||
|
||||
@@ -47,33 +104,92 @@ class StatementEmail extends Mailable
|
||||
$subject .= " - " . \Carbon\Carbon::createFromFormat('Ym', $this->statement->period_from)->locale('id')->isoFormat('MMMM Y');
|
||||
}
|
||||
|
||||
$email = $this->subject($subject)
|
||||
->view('webstatement::statements.email')
|
||||
->with([
|
||||
'statement' => $this->statement,
|
||||
'accountNumber' => $this->statement->account_number,
|
||||
'periodFrom' => $this->statement->period_from,
|
||||
'periodTo' => $this->statement->period_to,
|
||||
'isRange' => $this->statement->is_period_range,
|
||||
'requestType' => $this->statement->request_type,
|
||||
'batchId' => $this->statement->batch_id,
|
||||
'accounts' => Account::where('account_number', $this->statement->account_number)->first()
|
||||
]);
|
||||
|
||||
if ($this->isZip) {
|
||||
$fileName = "{$this->statement->account_number}_{$this->statement->period_from}_to_{$this->statement->period_to}.zip";
|
||||
$email->attach($this->filePath, [
|
||||
'as' => $fileName,
|
||||
'mime' => 'application/zip',
|
||||
]);
|
||||
} else {
|
||||
$fileName = "{$this->statement->account_number}_{$this->statement->period_from}.pdf";
|
||||
$email->attach($this->filePath, [
|
||||
'as' => $fileName,
|
||||
'mime' => 'application/pdf',
|
||||
]);
|
||||
// Add batch info for batch requests
|
||||
if ($this->statement->request_type && $this->statement->request_type !== 'single_account') {
|
||||
$subject .= " [{$this->statement->request_type}]";
|
||||
}
|
||||
|
||||
return $email;
|
||||
if ($this->statement->batch_id) {
|
||||
$subject .= " [Batch: {$this->statement->batch_id}]";
|
||||
}
|
||||
|
||||
return $subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate email body HTML
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function generateEmailBody(): string
|
||||
{
|
||||
try {
|
||||
// Get account data
|
||||
$account = Account::where('account_number', $this->statement->account_number)->first();
|
||||
|
||||
// Prepare data for view
|
||||
$data = [
|
||||
'statement' => $this->statement,
|
||||
'accountNumber' => $this->statement->account_number,
|
||||
'periodFrom' => $this->statement->period_from,
|
||||
'periodTo' => $this->statement->period_to,
|
||||
'isRange' => $this->statement->is_period_range,
|
||||
'requestType' => $this->statement->request_type,
|
||||
'batchId' => $this->statement->batch_id,
|
||||
'accounts' => $account
|
||||
];
|
||||
|
||||
// Render view to HTML
|
||||
return View::make('webstatement::statements.email', $data)->render();
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Failed to generate email body', [
|
||||
'account_number' => $this->statement->account_number,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
|
||||
// Fallback to simple HTML
|
||||
return $this->generateFallbackEmailBody();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate fallback email body
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function generateFallbackEmailBody(): string
|
||||
{
|
||||
$periodText = $this->statement->is_period_range
|
||||
? "periode {$this->statement->period_from} sampai {$this->statement->period_to}"
|
||||
: "periode " . \Carbon\Carbon::createFromFormat('Ym', $this->statement->period_from)->locale('id')->isoFormat('MMMM Y');
|
||||
|
||||
return "
|
||||
<html>
|
||||
<body>
|
||||
<h2>Statement Rekening Bank Artha Graha Internasional</h2>
|
||||
<p>Yth. Nasabah,</p>
|
||||
<p>Terlampir adalah statement rekening Anda untuk {$periodText}.</p>
|
||||
<p>Nomor Rekening: {$this->statement->account_number}</p>
|
||||
<p>Terima kasih atas kepercayaan Anda.</p>
|
||||
<br>
|
||||
<p>Salam,<br>Bank Artha Graha Internasional</p>
|
||||
</body>
|
||||
</html>
|
||||
";
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate attachment filename
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function generateAttachmentName(): string
|
||||
{
|
||||
if ($this->isZip) {
|
||||
return "{$this->statement->account_number}_{$this->statement->period_from}_to_{$this->statement->period_to}.zip";
|
||||
} else {
|
||||
return "{$this->statement->account_number}_{$this->statement->period_from}.pdf";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user