505 lines
19 KiB
PHP
505 lines
19 KiB
PHP
<?php
|
||
|
||
namespace App\Services;
|
||
|
||
use App\Models\MailTemplate;
|
||
use Illuminate\Support\Facades\Log;
|
||
use Illuminate\Support\Facades\DB;
|
||
use Carbon\Carbon;
|
||
|
||
/**
|
||
* SHJ メール送信処理サービス
|
||
*
|
||
* メールテンプレートを使用したメール送信処理を実行するビジネスロジック
|
||
* バッチ処理「SHJメール送信」の核となる処理を担当
|
||
*/
|
||
class ShjMailSendService
|
||
{
|
||
/**
|
||
* MailTemplate モデル
|
||
*
|
||
* @var MailTemplate
|
||
*/
|
||
protected $mailTemplateModel;
|
||
|
||
/**
|
||
* コンストラクタ
|
||
*
|
||
* @param MailTemplate $mailTemplateModel
|
||
*/
|
||
public function __construct(
|
||
MailTemplate $mailTemplateModel
|
||
) {
|
||
$this->mailTemplateModel = $mailTemplateModel;
|
||
}
|
||
|
||
/**
|
||
* SHJ-7 メール送信処理メイン実行
|
||
*
|
||
* 処理フロー:
|
||
* 【処理1】入力パラメーターをチェックする
|
||
* 【判断1】チェック結果
|
||
* 【処理2】メール送信テンプレート情報を取得する
|
||
* 【判断2】取得結果判定
|
||
* 【処理3】メールを送信する
|
||
* 【処理4】処理結果を返却する
|
||
*
|
||
* @param string $mailAddress メールアドレス
|
||
* @param string $backupMailAddress 予備メールアドレス
|
||
* @param int $mailTemplateId メールテンプレートID(使用プログラムID)
|
||
* @return array 処理結果 ['result' => 0|1, 'error_info' => string]
|
||
*/
|
||
public function executeMailSend(string $mailAddress, string $backupMailAddress, int $mailTemplateId): array
|
||
{
|
||
try {
|
||
Log::info('SHJ-7 メール送信処理開始', [
|
||
'mail_address' => $mailAddress,
|
||
'backup_mail_address' => $backupMailAddress,
|
||
'mail_template_id' => $mailTemplateId
|
||
]);
|
||
|
||
// 【処理1】入力パラメーターをチェックする
|
||
$paramCheckResult = $this->checkInputParameters($mailAddress, $backupMailAddress, $mailTemplateId);
|
||
|
||
// 【判断1】チェック結果
|
||
if (!$paramCheckResult['valid']) {
|
||
$errorInfo = $paramCheckResult['error_info'];
|
||
|
||
Log::warning('SHJ-7 パラメーターチェックNG', [
|
||
'error_info' => $errorInfo
|
||
]);
|
||
|
||
// 【処理4】処理結果を返却する(異常終了)
|
||
return [
|
||
'result' => 1,
|
||
'error_info' => $errorInfo
|
||
];
|
||
}
|
||
|
||
// 【処理2】メール送信テンプレート情報を取得する
|
||
$templateInfo = $this->getMailTemplateInfo($mailTemplateId);
|
||
|
||
// 【判断2】取得結果判定
|
||
if (empty($templateInfo)) {
|
||
// 0件の場合:取得NGの結果を設定する
|
||
$errorInfo = "メール送信NG:メール送信テンプレートが存在しません。/{$mailTemplateId}";
|
||
|
||
Log::warning('SHJ-7 メールテンプレート取得NG', [
|
||
'mail_template_id' => $mailTemplateId,
|
||
'error_info' => $errorInfo
|
||
]);
|
||
|
||
// 【処理4】処理結果を返却する(異常終了)
|
||
return [
|
||
'result' => 1,
|
||
'error_info' => $errorInfo
|
||
];
|
||
}
|
||
|
||
// 【処理3】メールを送信する
|
||
$mailSendResult = $this->sendMail($mailAddress, $backupMailAddress, $templateInfo);
|
||
|
||
if (!$mailSendResult['success']) {
|
||
$errorInfo = $mailSendResult['error_info'];
|
||
|
||
Log::error('SHJ-7 メール送信失敗', [
|
||
'error_info' => $errorInfo
|
||
]);
|
||
|
||
// 【処理4】処理結果を返却する(異常終了)
|
||
return [
|
||
'result' => 1,
|
||
'error_info' => $errorInfo
|
||
];
|
||
}
|
||
|
||
Log::info('SHJ-7 メール送信処理完了', [
|
||
'to_address' => $mailSendResult['to_address']
|
||
]);
|
||
|
||
// 【処理4】処理結果を返却する(正常終了)
|
||
return [
|
||
'result' => 0,
|
||
'error_info' => ''
|
||
];
|
||
|
||
} catch (\Exception $e) {
|
||
$errorInfo = 'メール送信NG:' . $e->getMessage();
|
||
|
||
Log::error('SHJ-7 メール送信処理例外エラー', [
|
||
'exception' => $e->getMessage(),
|
||
'trace' => $e->getTraceAsString()
|
||
]);
|
||
|
||
// 【処理4】処理結果を返却する(異常終了)
|
||
return [
|
||
'result' => 1,
|
||
'error_info' => $errorInfo
|
||
];
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 【処理1】入力パラメーターをチェックする
|
||
*
|
||
* SHJ-7仕様書に基づくチェック内容:
|
||
* 1. メールアドレス: 「メールアドレス」「予備メールアドレス」いずれか必須
|
||
* 2. 予備メールアドレス: 「メールアドレス」「予備メールアドレス」いずれか必須
|
||
* 3. 使用プログラムID: 必須
|
||
*
|
||
* エラーメッセージ形式: "パラメーターNG: 項目名/入力値"
|
||
* 複数エラーの場合は全角カンマ(、)で連結
|
||
*
|
||
* @param string $mailAddress メールアドレス
|
||
* @param string $backupMailAddress 予備メールアドレス
|
||
* @param int $mailTemplateId メールテンプレートID(使用プログラムID)
|
||
* @return array チェック結果 ['valid' => bool, 'error_info' => string]
|
||
*/
|
||
private function checkInputParameters(string $mailAddress, string $backupMailAddress, int $mailTemplateId): array
|
||
{
|
||
$errors = [];
|
||
|
||
try {
|
||
// 1. メールアドレスと予備メールアドレスのいずれか必須チェック
|
||
// 両方とも空の場合は、それぞれ別エラーとして追加
|
||
if (empty($mailAddress) && empty($backupMailAddress)) {
|
||
$errors[] = "パラメーターNG:メールアドレス/<空>";
|
||
$errors[] = "パラメーターNG:予備メールアドレス/<空>";
|
||
} else {
|
||
// いずれかに値がある場合は、形式チェックを実施
|
||
// 2. メールアドレス形式チェック(値がある場合のみ)
|
||
if (!empty($mailAddress) && !filter_var($mailAddress, FILTER_VALIDATE_EMAIL)) {
|
||
$errors[] = "パラメーターNG:メールアドレス/{$mailAddress}";
|
||
}
|
||
|
||
// 3. 予備メールアドレス形式チェック(値がある場合のみ)
|
||
if (!empty($backupMailAddress) && !filter_var($backupMailAddress, FILTER_VALIDATE_EMAIL)) {
|
||
$errors[] = "パラメーターNG:予備メールアドレス/{$backupMailAddress}";
|
||
}
|
||
}
|
||
|
||
// 4. 使用プログラムID(メールテンプレートID)必須チェック
|
||
if (empty($mailTemplateId) || $mailTemplateId <= 0) {
|
||
$errors[] = "パラメーターNG:使用プログラムID/{$mailTemplateId}";
|
||
}
|
||
|
||
// エラーがある場合
|
||
if (!empty($errors)) {
|
||
// 複数のエラーがある場合は全角カンマ(、)で連結
|
||
$errorInfo = implode('、', $errors);
|
||
|
||
Log::warning('SHJ-7 入力パラメーターチェックNG', [
|
||
'mail_address' => $mailAddress,
|
||
'backup_mail_address' => $backupMailAddress,
|
||
'mail_template_id' => $mailTemplateId,
|
||
'error_info' => $errorInfo
|
||
]);
|
||
|
||
return [
|
||
'valid' => false,
|
||
'error_info' => $errorInfo
|
||
];
|
||
}
|
||
|
||
// 正常終了
|
||
Log::info('SHJ-7 入力パラメーターチェックOK', [
|
||
'mail_address' => $mailAddress,
|
||
'backup_mail_address' => $backupMailAddress,
|
||
'mail_template_id' => $mailTemplateId
|
||
]);
|
||
|
||
return [
|
||
'valid' => true,
|
||
'error_info' => ''
|
||
];
|
||
|
||
} catch (\Exception $e) {
|
||
$errorInfo = 'パラメーターチェック中にエラーが発生:' . $e->getMessage();
|
||
|
||
Log::error('SHJ-7 入力パラメーターチェック例外エラー', [
|
||
'error' => $e->getMessage(),
|
||
'trace' => $e->getTraceAsString()
|
||
]);
|
||
|
||
return [
|
||
'valid' => false,
|
||
'error_info' => $errorInfo
|
||
];
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 【処理2】メール送信テンプレート情報を取得する
|
||
*
|
||
* SHJ-7仕様書に基づくSQLクエリ:
|
||
* SELECT エリアマネージャー同報, bccアドレス, 件名, 本文
|
||
* FROM メール送信テンプレート
|
||
* WHERE 使用プログラムID = 入力パラメーター.使用プログラムID
|
||
* AND 使用フラグ = 1
|
||
*
|
||
* @param int $mailTemplateId メールテンプレートID(使用プログラムID)
|
||
* @return MailTemplate|null メールテンプレート情報
|
||
*/
|
||
private function getMailTemplateInfo(int $mailTemplateId): ?MailTemplate
|
||
{
|
||
try {
|
||
// SHJ-7仕様: 使用プログラムID(pg_id)で検索、使用フラグ=1
|
||
$templateInfo = $this->mailTemplateModel::where('pg_id', $mailTemplateId)
|
||
->where('use_flag', 1)
|
||
->first();
|
||
|
||
if ($templateInfo) {
|
||
Log::info('SHJ-7 メールテンプレート情報取得完了', [
|
||
'mail_template_id' => $mailTemplateId,
|
||
'template_found' => true,
|
||
'subject' => $templateInfo->getSubject(),
|
||
'mgr_cc_flag' => $templateInfo->isManagerCcEnabled(),
|
||
'has_bcc' => !empty($templateInfo->getBccAddress())
|
||
]);
|
||
} else {
|
||
Log::warning('SHJ-7 メールテンプレート情報取得結果0件', [
|
||
'mail_template_id' => $mailTemplateId,
|
||
'template_found' => false
|
||
]);
|
||
}
|
||
|
||
return $templateInfo;
|
||
|
||
} catch (\Exception $e) {
|
||
Log::error('SHJ-7 メールテンプレート情報取得エラー', [
|
||
'mail_template_id' => $mailTemplateId,
|
||
'error' => $e->getMessage(),
|
||
'trace' => $e->getTraceAsString()
|
||
]);
|
||
|
||
throw $e;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 【処理3】メールを送信する
|
||
*
|
||
* SHJ-7仕様書に基づくmb_send_mail関数使用:
|
||
* - 送信先: 入力パラメーター.メールアドレス(空なら予備メールアドレス)
|
||
* - タイトル: 処理2.件名
|
||
* - 本文: 処理2.本文
|
||
* - 追加ヘッダ: 処理2.bccアドレス(※値が設定されている場合のみ)
|
||
*
|
||
* ※待ち時間: 仕様では「一定の待ち時間を設ける」とあるが、現時点では実装しない(0秒)
|
||
*
|
||
* @param string $mailAddress メールアドレス
|
||
* @param string $backupMailAddress 予備メールアドレス
|
||
* @param MailTemplate $templateInfo テンプレート情報
|
||
* @return array 送信結果 ['success' => bool, 'error_info' => string, 'to_address' => string]
|
||
*/
|
||
private function sendMail(string $mailAddress, string $backupMailAddress, MailTemplate $templateInfo): array
|
||
{
|
||
try {
|
||
// 送信先アドレス決定(優先: メールアドレス、代替: 予備メールアドレス)
|
||
$toAddress = !empty($mailAddress) ? $mailAddress : $backupMailAddress;
|
||
|
||
// 処理2で取得したメール内容を取得
|
||
$subject = $templateInfo->getSubject() ?? '';
|
||
$message = $templateInfo->getText() ?? '';
|
||
|
||
// 追加ヘッダ設定(BCC、From等)
|
||
$headers = $this->buildMailHeaders($templateInfo);
|
||
|
||
Log::info('SHJ-7 メール送信準備完了', [
|
||
'to_address' => $toAddress,
|
||
'subject' => $subject,
|
||
'has_bcc' => !empty($templateInfo->getBccAddress()),
|
||
'mgr_cc_flag' => $templateInfo->isManagerCcEnabled()
|
||
]);
|
||
|
||
// mb_send_mail関数を使用してメール送信
|
||
$sendResult = mb_send_mail(
|
||
$toAddress, // 送信先
|
||
$subject, // 件名(タイトル)
|
||
$message, // 本文
|
||
$headers // 追加ヘッダ
|
||
);
|
||
|
||
if ($sendResult) {
|
||
Log::info('SHJ-7 メール送信成功', [
|
||
'to_address' => $toAddress,
|
||
'subject' => $subject
|
||
]);
|
||
|
||
return [
|
||
'success' => true,
|
||
'error_info' => '',
|
||
'to_address' => $toAddress
|
||
];
|
||
} else {
|
||
// mb_send_mail がfalseを返した場合
|
||
$errorInfo = 'メール送信NG:mb_send_mail関数がfalseを返しました';
|
||
Log::error('SHJ-7 メール送信失敗', [
|
||
'to_address' => $toAddress,
|
||
'subject' => $subject,
|
||
'error_info' => $errorInfo
|
||
]);
|
||
|
||
return [
|
||
'success' => false,
|
||
'error_info' => $errorInfo
|
||
];
|
||
}
|
||
|
||
} catch (\Exception $e) {
|
||
$errorInfo = 'メール送信NG:' . $e->getMessage();
|
||
Log::error('SHJ-7 メール送信例外エラー', [
|
||
'error' => $e->getMessage(),
|
||
'trace' => $e->getTraceAsString()
|
||
]);
|
||
|
||
return [
|
||
'success' => false,
|
||
'error_info' => $errorInfo
|
||
];
|
||
}
|
||
}
|
||
|
||
/**
|
||
* メールヘッダを構築
|
||
*
|
||
* SHJ-7仕様書に基づく追加ヘッダ設定:
|
||
* - 追加ヘッダ: 処理2.bccアドレス(※値が設定されている場合のみ)
|
||
* - From: システム設定から取得
|
||
* - エリアマネージャー同報: フラグが有効な場合はログ出力のみ(実装保留)
|
||
*
|
||
* @param MailTemplate $templateInfo テンプレート情報
|
||
* @return string メールヘッダ
|
||
*/
|
||
private function buildMailHeaders(MailTemplate $templateInfo): string
|
||
{
|
||
$headers = [];
|
||
|
||
// BCCアドレス設定(値が設定されている場合のみ追加)
|
||
$bccAddress = $templateInfo->getBccAddress();
|
||
if (!empty($bccAddress)) {
|
||
$headers[] = "Bcc: {$bccAddress}";
|
||
}
|
||
|
||
// エリアマネージャー同報フラグが有効な場合
|
||
// ※SHJ-7では実装しない(仕様詳細不明)。ログ出力のみ。
|
||
if ($templateInfo->isManagerCcEnabled()) {
|
||
Log::info('SHJ-7 エリアマネージャー同報フラグが有効', [
|
||
'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);
|
||
}
|
||
|
||
|
||
/**
|
||
* 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
|
||
];
|
||
}
|
||
}
|
||
} |