Files
webstatement/app/Mail/StatementEmail.php
Daeng Deni Mardaeni fabc35e729 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>
2025-06-11 11:41:57 +07:00

196 lines
6.0 KiB
PHP

<?php
namespace Modules\Webstatement\Mail;
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;
/**
* Service untuk mengirim email statement menggunakan PHPMailer
* dengan dukungan autentikasi NTLM/GSSAPI
*/
class StatementEmail
{
protected $statement;
protected $filePath;
protected $isZip;
protected $phpMailerService;
/**
* Create a new message instance.
* Membuat instance email baru untuk pengiriman statement
*
* @param PrintStatementLog $statement
* @param string $filePath
* @param bool $isZip
*/
public function __construct(PrintStatementLog $statement, $filePath, $isZip = false)
{
$this->statement = $statement;
$this->filePath = $filePath;
$this->isZip = $isZip;
$this->phpMailerService = new PHPMailerService();
}
/**
* Kirim email statement
*
* @param string $emailAddress
* @return bool
*/
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';
if ($this->statement->is_period_range) {
$subject .= " - {$this->statement->period_from} to {$this->statement->period_to}";
} else {
$subject .= " - " . \Carbon\Carbon::createFromFormat('Ym', $this->statement->period_from)->locale('id')->isoFormat('MMMM Y');
}
// Add batch info for batch requests
if ($this->statement->request_type && $this->statement->request_type !== 'single_account') {
$subject .= " [{$this->statement->request_type}]";
}
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";
}
}
}