so-manager-dev.com/app/Services/ShjMailSendService.php
2025-09-19 19:01:21 +09:00

545 lines
20 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Services;
use App\Models\MailTemplate;
use App\Models\Batch\BatchLog;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
/**
* SHJ メール送信処理サービス
*
* メールテンプレートを使用したメール送信処理を実行するビジネスロジック
* バッチ処理「SHJメール送信」の核となる処理を担当
*/
class ShjMailSendService
{
/**
* MailTemplate モデル
*
* @var MailTemplate
*/
protected $mailTemplateModel;
/**
* BatchLog モデル
*
* @var BatchLog
*/
protected $batchLogModel;
/**
* コンストラクタ
*
* @param MailTemplate $mailTemplateModel
* @param BatchLog $batchLogModel
*/
public function __construct(
MailTemplate $mailTemplateModel,
BatchLog $batchLogModel
) {
$this->mailTemplateModel = $mailTemplateModel;
$this->batchLogModel = $batchLogModel;
}
/**
* SHJ メール送信処理メイン実行
*
* 処理フロー:
* 【処理1】入力パラメーターをチェックする
* 【処理2】メール送信テンプレート情報を取得する
* 【判断2】取得結果判定
* 【処理3】メールを送信する
* 【処理4】処理結果を返却する
*
* @param string $mailAddress メールアドレス
* @param string $backupMailAddress 予備メールアドレス
* @param int $mailTemplateId メールテンプレートID
* @return array 処理結果
*/
public function executeMailSend(string $mailAddress, string $backupMailAddress, int $mailTemplateId): array
{
$batchLogId = null;
try {
// バッチ処理開始ログ作成(実際のコマンド名を記録)
$batchLog = BatchLog::createBatchLog(
'shj-mail-send',
BatchLog::STATUS_START,
[
'mail_address' => $mailAddress,
'backup_mail_address' => $backupMailAddress,
'mail_template_id' => $mailTemplateId
],
'SHJ メール送信処理開始'
);
$batchLogId = $batchLog->id;
Log::info('SHJ メール送信処理開始', [
'batch_log_id' => $batchLogId,
'mail_address' => $mailAddress,
'backup_mail_address' => $backupMailAddress,
'mail_template_id' => $mailTemplateId
]);
// 【処理1】入力パラメーターをチェックする
$paramCheckResult = $this->checkInputParameters($mailAddress, $backupMailAddress, $mailTemplateId);
if (!$paramCheckResult['valid']) {
$this->updateBatchLog($batchLogId, 'error', $paramCheckResult['message']);
return [
'success' => false,
'result_code' => 1, // 異常終了
'message' => $paramCheckResult['message'],
'batch_log_id' => $batchLogId
];
}
// 【処理2】メール送信テンプレート情報を取得する
$templateInfo = $this->getMailTemplateInfo($mailTemplateId);
// 【判断2】取得結果判定
if (empty($templateInfo)) {
$message = "メールテンプレートが存在しません。テンプレートID: {$mailTemplateId}";
$this->updateBatchLog($batchLogId, 'error', $message);
return [
'success' => false,
'result_code' => 1, // 異常終了
'message' => $message,
'batch_log_id' => $batchLogId
];
}
// 【処理3】メールを送信する
$mailSendResult = $this->sendMail($mailAddress, $backupMailAddress, $templateInfo);
if (!$mailSendResult['success']) {
$this->updateBatchLog($batchLogId, 'error', $mailSendResult['message']);
return [
'success' => false,
'result_code' => 1, // 異常終了
'message' => $mailSendResult['message'],
'batch_log_id' => $batchLogId
];
}
// バッチ処理完了ログ更新
$this->updateBatchLog($batchLogId, 'success', 'SHJ メール送信処理正常完了');
Log::info('SHJ メール送信処理完了', [
'batch_log_id' => $batchLogId,
'mail_send_result' => $mailSendResult
]);
// 【処理4】処理結果を返却する
return [
'success' => true,
'result_code' => 0, // 正常終了
'message' => 'SHJ メール送信処理が正常に完了しました',
'mail_send_result' => $mailSendResult,
'batch_log_id' => $batchLogId
];
} catch (\Exception $e) {
$errorMessage = 'SHJ メール送信処理でエラーが発生: ' . $e->getMessage();
if ($batchLogId) {
$this->updateBatchLog($batchLogId, 'error', $errorMessage);
}
Log::error('SHJ メール送信処理エラー', [
'batch_log_id' => $batchLogId,
'exception' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
return [
'success' => false,
'result_code' => 1, // 異常終了
'message' => $errorMessage,
'details' => $e->getMessage(),
'batch_log_id' => $batchLogId
];
}
}
/**
* 【処理1】入力パラメーターをチェックする
*
* 仕様書に基づく詳細チェック:
* - メールアドレス形式チェック
* - テンプレートID存在性チェック
*
* @param string $mailAddress メールアドレス
* @param string $backupMailAddress 予備メールアドレス
* @param int $mailTemplateId メールテンプレートID
* @return array チェック結果
*/
private function checkInputParameters(string $mailAddress, string $backupMailAddress, int $mailTemplateId): array
{
try {
// メールアドレス存在チェック(いずれか必須)
if (empty($mailAddress) && empty($backupMailAddress)) {
return [
'valid' => false,
'message' => 'パラメーターNG: メールアドレスまたは予備メールアドレスのいずれかは必須です'
];
}
// メールアドレス形式チェック
if (!empty($mailAddress) && !filter_var($mailAddress, FILTER_VALIDATE_EMAIL)) {
return [
'valid' => false,
'message' => 'パラメーターNG: メールアドレスの形式が正しくありません'
];
}
if (!empty($backupMailAddress) && !filter_var($backupMailAddress, FILTER_VALIDATE_EMAIL)) {
return [
'valid' => false,
'message' => 'パラメーターNG: 予備メールアドレスの形式が正しくありません'
];
}
// メールテンプレートID形式チェック
if ($mailTemplateId <= 0) {
return [
'valid' => false,
'message' => 'パラメーターNG: メールテンプレートIDは正の整数である必要があります'
];
}
Log::info('入力パラメーターチェック完了', [
'mail_address' => $mailAddress,
'backup_mail_address' => $backupMailAddress,
'mail_template_id' => $mailTemplateId
]);
return [
'valid' => true,
'message' => 'パラメーターチェックOK'
];
} catch (\Exception $e) {
Log::error('入力パラメーターチェックエラー', [
'error' => $e->getMessage()
]);
return [
'valid' => false,
'message' => 'パラメーターチェック中にエラーが発生しました: ' . $e->getMessage()
];
}
}
/**
* 【処理2】メール送信テンプレート情報を取得する
*
* 仕様書に基づくSQLクエリ:
* SELECT エリアマネージャー同報, bccアドレス, 件名, 本文
* FROM メール送信テンプレート
* WHERE 使用プログラムID = 入力パラメーター使用プログラムID
* AND 使用フラグ = 1
*
* @param int $mailTemplateId メールテンプレートID使用プログラムIDとして扱う
* @return MailTemplate|null メールテンプレート情報
*/
private function getMailTemplateInfo(int $mailTemplateId): ?MailTemplate
{
try {
// 仕様書に記載されたSQLクエリに基づくメールテンプレート情報取得
// 注意: 仕様書では「使用プログラムID」を条件にしているが、
// 入力パラメーターは「メールテンプレートID」なので、pg_idで検索
$templateInfo = $this->mailTemplateModel::where('pg_id', $mailTemplateId)
->where('use_flag', 1)
->first();
if ($templateInfo) {
Log::info('メールテンプレート情報取得完了', [
'mail_template_id' => $mailTemplateId,
'template_found' => true,
'subject' => $templateInfo->getSubject()
]);
} else {
Log::warning('メールテンプレート情報取得結果', [
'mail_template_id' => $mailTemplateId,
'template_found' => false,
'message' => 'テンプレートが見つかりません'
]);
}
return $templateInfo;
} catch (\Exception $e) {
Log::error('メールテンプレート情報取得エラー', [
'mail_template_id' => $mailTemplateId,
'error' => $e->getMessage()
]);
throw $e;
}
}
/**
* 【処理3】メールを送信する
*
* 仕様書に基づくmb_send_mail関数使用:
* - 送信者: 処理2で取得したメールアドレス処理1で予備メールアドレス
* - タイトル: 処理2で取得したタイトル
* - 本文: 処理2で取得した本文※現在の文字列は「So-Manager一般的なWebサイト内部処理」参照
* - 追加ヘッダ: 処理2で取得したbccアドレス※値が設定されている場合のみ
*
* @param string $mailAddress メールアドレス
* @param string $backupMailAddress 予備メールアドレス
* @param MailTemplate $templateInfo テンプレート情報
* @return array 送信結果
*/
private function sendMail(string $mailAddress, string $backupMailAddress, MailTemplate $templateInfo): array
{
try {
// 送信先アドレス決定(優先: メールアドレス、代替: 予備メールアドレス)
$toAddress = !empty($mailAddress) ? $mailAddress : $backupMailAddress;
// メール内容取得
$subject = $templateInfo->getSubject() ?? '';
$message = $templateInfo->getText() ?? '';
// 追加ヘッダ設定
$headers = $this->buildMailHeaders($templateInfo);
Log::info('メール送信準備完了', [
'to_address' => $toAddress,
'subject' => $subject,
'has_bcc' => !empty($templateInfo->getBccAddress()),
'manager_cc_enabled' => $templateInfo->isManagerCcEnabled()
]);
// mb_send_mail関数を使用してメール送信
$sendResult = mb_send_mail(
$toAddress, // 送信先
$subject, // 件名
$message, // 本文
$headers // 追加ヘッダ
);
if ($sendResult) {
Log::info('メール送信成功', [
'to_address' => $toAddress,
'subject' => $subject
]);
return [
'success' => true,
'message' => 'メール送信が正常に完了しました',
'to_address' => $toAddress,
'subject' => $subject
];
} else {
$errorMessage = 'mb_send_mail関数でメール送信に失敗しました';
Log::error('メール送信失敗', [
'to_address' => $toAddress,
'subject' => $subject,
'error' => $errorMessage
]);
return [
'success' => false,
'message' => $errorMessage
];
}
} catch (\Exception $e) {
$errorMessage = 'メール送信中にエラーが発生: ' . $e->getMessage();
Log::error('メール送信エラー', [
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
return [
'success' => false,
'message' => $errorMessage
];
}
}
/**
* メールヘッダを構築
*
* 仕様書に基づく設定:
* - BCCアドレス: 値が設定されている場合のみ追加
* - エリアマネージャー同報: フラグが有効な場合の処理
*
* @param MailTemplate $templateInfo テンプレート情報
* @return string メールヘッダ
*/
private function buildMailHeaders(MailTemplate $templateInfo): string
{
$headers = [];
// BCCアドレス設定値が設定されている場合のみ
$bccAddress = $templateInfo->getBccAddress();
if (!empty($bccAddress)) {
$headers[] = "Bcc: {$bccAddress}";
}
// エリアマネージャー同報フラグが有効な場合
// ※具体的な処理内容は仕様書に詳細がないため、ログ出力のみ
if ($templateInfo->isManagerCcEnabled()) {
Log::info('エリアマネージャー同報フラグが有効です', [
'mail_template_id' => $templateInfo->mail_template_id
]);
// 実際のエリアマネージャーアドレス取得・設定処理は追加仕様が必要
}
// From設定システム設定から取得
$fromAddress = config('mail.from.address', 'noreply@so-manager.com');
$headers[] = "From: {$fromAddress}";
// Content-Type設定日本語対応
$headers[] = "Content-Type: text/plain; charset=UTF-8";
return implode("\r\n", $headers);
}
/**
* バッチログ作成
*
* @param string $processName プロセス名
* @param string $status ステータス
* @param array $params パラメータ
* @return int バッチログID
*/
private function createBatchLog(string $processName, string $status, array $params = []): int
{
return $this->batchLogModel->create([
'process_name' => $processName,
'status' => $status,
'start_time' => now(),
'parameters' => json_encode($params),
'message' => 'バッチ処理開始'
])->id;
}
/**
* バッチログ更新
*
* @param int $batchLogId バッチログID
* @param string $status ステータス
* @param string $message メッセージ
* @return void
*/
private function updateBatchLog(int $batchLogId, string $status, string $message): void
{
$this->batchLogModel->where('id', $batchLogId)->update([
'status' => $status,
'end_time' => now(),
'message' => $message
]);
}
/**
* SHJ-12 未払い者通知メール送信
*
* SHJ-12から呼び出される専用メール送信メソッド
* 未払い者への通知メールを送信する
*
* @param array $mailParams メール送信パラメータ
* @return array 送信結果
*/
public function sendUnpaidNotificationMail(array $mailParams): array
{
try {
// パラメータ展開
$toEmail = $mailParams['to_email'] ?? '';
$userName = $mailParams['user_name'] ?? '';
$parkName = $mailParams['park_name'] ?? '';
$billingAmount = $mailParams['billing_amount'] ?? 0;
$contractId = $mailParams['contract_id'] ?? '';
// 未払い者通知専用のメールテンプレートID仮定: 1
// 実際の運用では設定ファイルまたはデータベースから取得
$mailTemplateId = 1;
// メールテンプレート情報取得
$templateInfo = $this->getMailTemplateInfo($mailTemplateId);
if (!$templateInfo) {
return [
'success' => false,
'message' => '未払い者通知用メールテンプレートが見つかりません'
];
}
// メール件名とメッセージのカスタマイズ
$subject = str_replace(
['{park_name}', '{user_name}'],
[$parkName, $userName],
$templateInfo->getSubject()
);
$message = str_replace(
['{user_name}', '{park_name}', '{billing_amount}', '{contract_id}'],
[$userName, $parkName, number_format($billingAmount), $contractId],
$templateInfo->getText()
);
// 追加ヘッダ設定
$headers = $this->buildMailHeaders($templateInfo);
Log::info('SHJ-12 未払い者通知メール送信準備完了', [
'to_email' => $toEmail,
'user_name' => $userName,
'billing_amount' => $billingAmount,
'contract_id' => $contractId
]);
// メール送信実行
$sendResult = mb_send_mail(
$toEmail, // 送信先
$subject, // 件名
$message, // 本文
$headers // 追加ヘッダ
);
if ($sendResult) {
Log::info('SHJ-12 未払い者通知メール送信成功', [
'to_email' => $toEmail,
'contract_id' => $contractId
]);
return [
'success' => true,
'message' => '未払い者通知メール送信完了'
];
} else {
$errorMessage = '未払い者通知メール送信に失敗しました';
Log::error('SHJ-12 未払い者通知メール送信失敗', [
'to_email' => $toEmail,
'contract_id' => $contractId,
'error' => $errorMessage
]);
return [
'success' => false,
'message' => $errorMessage
];
}
} catch (\Exception $e) {
$errorMessage = 'SHJ-12 未払い者通知メール送信エラー: ' . $e->getMessage();
Log::error('SHJ-12 未払い者通知メール送信エラー', [
'error' => $e->getMessage(),
'mail_params' => $mailParams
]);
return [
'success' => false,
'message' => $errorMessage
];
}
}
}