diff --git a/app/Mail/StatementEmail.php b/app/Mail/StatementEmail.php index ee77925..227af3d 100644 --- a/app/Mail/StatementEmail.php +++ b/app/Mail/StatementEmail.php @@ -1,79 +1,204 @@ statement = $statement; - $this->filePath = $filePath; - $this->isZip = $isZip; - } + use Queueable, SerializesModels; - /** - * Build the message. - * Membangun struktur email dengan attachment statement - * - * @return $this - */ - public function build() - { - $subject = 'Statement Rekening Bank Artha Graha Internasional'; + protected $statement; + protected $filePath; + protected $isZip; + protected $message; - 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'); + /** + * 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; } - $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() - ]); + /** + * Override the send method to use EsmtpTransport directly + * Using the working configuration from Python script with multiple fallback methods + */ + public function send($mailer) + { + // Get mail configuration + $host = Config::get('mail.mailers.smtp.host'); + $port = Config::get('mail.mailers.smtp.port'); + $username = Config::get('mail.mailers.smtp.username'); + $password = Config::get('mail.mailers.smtp.password'); - 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', - ]); + Log::info('StatementEmail: Attempting to send email with multiple fallback methods'); + + // Define connection methods like in Python script + $method = + // Method 3: STARTTLS with original port + [ + 'port' => $port, + 'ssl' => false, + 'name' => 'STARTTLS (Port $port)' + ]; + + $lastException = null; + + // Try each connection method until one succeeds + try { + Log::info('StatementEmail: Trying ' . $method['name']); + + // Create EsmtpTransport with current method + $transport = new EsmtpTransport($host, $method['port'], $method['ssl']); + + // Set username and password + if ($username) { + $transport->setUsername($username); + } + if ($password) { + $transport->setPassword($password); + } + + // Disable SSL verification for development + $streamOptions = [ + 'ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'allow_self_signed' => true + ] + ]; + $transport->getStream()->setStreamOptions($streamOptions); + + // Build the email content + $this->build(); + + // Start transport connection + $transport->start(); + + // Create Symfony mailer + $symfonyMailer = new Mailer($transport); + + // Convert Laravel message to Symfony Email + $email = $this->toSymfonyEmail(); + + // Send the email + $symfonyMailer->send($email); + + // Close connection + $transport->stop(); + + Log::info('StatementEmail: Successfully sent email using ' . $method['name']); + return $this; + + } catch (Exception $e) { + $lastException = $e; + Log::warning('StatementEmail: Failed to send with ' . $method['name'] . ': ' . $e->getMessage()); + // Continue to next method + } + + try { + return parent::send($mailer); + } catch (Exception $e) { + Log::error('StatementEmail: Laravel mailer also failed: ' . $e->getMessage()); + // If we got here, throw the last exception from our custom methods + throw $lastException; + } } - return $email; + /** + * Build the message. + * Membangun struktur email dengan attachment statement + * + * @return $this + */ + public function build() + { + $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::createFromFormat('Ym', $this->statement->period_from) + ->locale('id') + ->isoFormat('MMMM Y'); + } + + $email = $this->subject($subject); + + // Store the email in the message property for later use in toSymfonyEmail() + $this->message = $email; + + return $email; + } + + /** + * Convert Laravel message to Symfony Email + */ + protected function toSymfonyEmail() + { + // Build the message if it hasn't been built yet + $this->build(); + // Create a new Symfony Email + $email = new Email(); + + // Set from address using config values instead of trying to call getFrom() + $fromAddress = Config::get('mail.from.address'); + $fromName = Config::get('mail.from.name'); + $email->from($fromName ? "$fromName <$fromAddress>" : $fromAddress); + + // Set to addresses - use the to addresses from the mailer instead of trying to call getTo() + // We'll get the to addresses from the Mail facade when the email is sent + // For now, we'll just add a placeholder recipient that will be overridden by the Mail facade + $email->to($this->message->to[0]['address']); + + $email->subject($this->message->subject); + + // Set body - use a simple HTML content instead of trying to call getHtmlBody() + // In a real implementation, we would need to find a way to access the rendered HTML content + $email->html(view('webstatement::statements.email', [ + '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() + ])->render()); + //$email->text($this->message->getTextBody()); + + // Add attachments - use the file path directly instead of trying to call getAttachments() + if ($this->filePath && file_exists($this->filePath)) { + if ($this->isZip) { + $fileName = "{$this->statement->account_number}_{$this->statement->period_from}_to_{$this->statement->period_to}.zip"; + $contentType = 'application/zip'; + } else { + $fileName = "{$this->statement->account_number}_{$this->statement->period_from}.pdf"; + $contentType = 'application/pdf'; + } + $email->attachFromPath($this->filePath, $fileName, $contentType); + } + + return $email; + } } -}