feat: SHJ-3 定期更新リマインダー処理実装
- ShjThreeCommand.php: 無引数実行のArtisanコマンド実装 - ShjThreeService.php: メインビジネスロジック実装
This commit is contained in:
parent
b280edf5f6
commit
1e324a73e2
108
app/Console/Commands/ShjThreeCommand.php
Normal file
108
app/Console/Commands/ShjThreeCommand.php
Normal file
@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use App\Services\ShjThreeService;
|
||||
|
||||
/**
|
||||
* SHJ-3 定期更新リマインダー処理コマンド
|
||||
*
|
||||
* 駐輪場の定期契約更新対象者に対するリマインダー処理を実行する
|
||||
* バックグラウンドで実行される定期バッチ処理
|
||||
*/
|
||||
class ShjThreeCommand extends Command
|
||||
{
|
||||
/**
|
||||
* コンソールコマンドの名前とシグネチャ
|
||||
*
|
||||
* 引数なし - 全ての駐輪場を対象に処理を実行
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'shj:3';
|
||||
|
||||
/**
|
||||
* コンソールコマンドの説明
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'SHJ-3 定期更新リマインダー処理 - 定期契約更新対象者へのリマインダー送信を実行';
|
||||
|
||||
/**
|
||||
* SHJ-3サービスクラス
|
||||
*
|
||||
* @var ShjThreeService
|
||||
*/
|
||||
protected $shjThreeService;
|
||||
|
||||
/**
|
||||
* コンストラクタ
|
||||
*
|
||||
* @param ShjThreeService $shjThreeService
|
||||
*/
|
||||
public function __construct(ShjThreeService $shjThreeService)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->shjThreeService = $shjThreeService;
|
||||
}
|
||||
|
||||
/**
|
||||
* コンソールコマンドを実行
|
||||
*
|
||||
* 処理フロー:
|
||||
* 1. 駐輪場マスタ情報取得
|
||||
* 2. 各駐輪場の実行タイミングチェック
|
||||
* 3. 定期更新対象者取得とリマインダー送信
|
||||
* 4. バッチログ作成
|
||||
* 5. 処理結果返却
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
try {
|
||||
// 開始ログ出力
|
||||
$startTime = now();
|
||||
$this->info('SHJ-3 定期更新リマインダー処理を開始します。');
|
||||
|
||||
Log::info('SHJ-3 定期更新リマインダー処理開始', [
|
||||
'start_time' => $startTime
|
||||
]);
|
||||
|
||||
// SHJ-3メイン処理実行
|
||||
$result = $this->shjThreeService->executeReminderProcess();
|
||||
|
||||
$endTime = now();
|
||||
$this->info('SHJ-3 定期更新リマインダー処理が完了しました。');
|
||||
$this->info("処理時間: {$startTime->diffInSeconds($endTime)}秒");
|
||||
|
||||
// 処理結果表示
|
||||
$this->line('=== 処理結果 ===');
|
||||
$this->line("対象駐輪場数: {$result['processed_parks_count']}");
|
||||
$this->line("対象者総数: {$result['total_target_users']}");
|
||||
$this->line("メール送信成功: {$result['mail_success_count']}件");
|
||||
$this->line("メール送信失敗: {$result['mail_error_count']}件");
|
||||
$this->line("オペレーターキュー追加: {$result['operator_queue_count']}件");
|
||||
|
||||
Log::info('SHJ-3 定期更新リマインダー処理完了', [
|
||||
'end_time' => $endTime,
|
||||
'duration_seconds' => $startTime->diffInSeconds($endTime),
|
||||
'result' => $result
|
||||
]);
|
||||
|
||||
return $result['success'] ? self::SUCCESS : self::FAILURE;
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$this->error('SHJ-3 定期更新リマインダー処理で予期しないエラーが発生しました: ' . $e->getMessage());
|
||||
|
||||
Log::error('SHJ-3 定期更新リマインダー処理例外エラー', [
|
||||
'exception' => $e->getMessage(),
|
||||
'trace' => $e->getTraceAsString()
|
||||
]);
|
||||
|
||||
return self::FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
796
app/Services/ShjThreeService.php
Normal file
796
app/Services/ShjThreeService.php
Normal file
@ -0,0 +1,796 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\Park;
|
||||
use App\Models\User;
|
||||
use App\Models\RegularContract;
|
||||
use App\Models\Batch\BatchLog;
|
||||
use App\Services\ShjMailSendService;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Carbon\Carbon;
|
||||
|
||||
/**
|
||||
* SHJ-3 定期更新リマインダー処理サービス
|
||||
*
|
||||
* 駐輪場の定期契約更新対象者に対するリマインダー処理を実行するビジネスロジック
|
||||
* バッチ処理「SHJ-3定期更新リマインダー」の核となる処理を担当
|
||||
*/
|
||||
class ShjThreeService
|
||||
{
|
||||
/**
|
||||
* Park モデル
|
||||
*
|
||||
* @var Park
|
||||
*/
|
||||
protected $parkModel;
|
||||
|
||||
/**
|
||||
* User モデル
|
||||
*
|
||||
* @var User
|
||||
*/
|
||||
protected $userModel;
|
||||
|
||||
/**
|
||||
* RegularContract モデル
|
||||
*
|
||||
* @var RegularContract
|
||||
*/
|
||||
protected $contractModel;
|
||||
|
||||
/**
|
||||
* BatchLog モデル
|
||||
*
|
||||
* @var BatchLog
|
||||
*/
|
||||
protected $batchLogModel;
|
||||
|
||||
/**
|
||||
* ShjMailSendService
|
||||
*
|
||||
* @var ShjMailSendService
|
||||
*/
|
||||
protected $mailSendService;
|
||||
|
||||
/**
|
||||
* コンストラクタ
|
||||
*
|
||||
* @param Park $parkModel
|
||||
* @param User $userModel
|
||||
* @param RegularContract $contractModel
|
||||
* @param BatchLog $batchLogModel
|
||||
* @param ShjMailSendService $mailSendService
|
||||
*/
|
||||
public function __construct(
|
||||
Park $parkModel,
|
||||
User $userModel,
|
||||
RegularContract $contractModel,
|
||||
BatchLog $batchLogModel,
|
||||
ShjMailSendService $mailSendService
|
||||
) {
|
||||
$this->parkModel = $parkModel;
|
||||
$this->userModel = $userModel;
|
||||
$this->contractModel = $contractModel;
|
||||
$this->batchLogModel = $batchLogModel;
|
||||
$this->mailSendService = $mailSendService;
|
||||
}
|
||||
|
||||
/**
|
||||
* SHJ-3 定期更新リマインダー処理メイン実行
|
||||
*
|
||||
* 処理フロー:
|
||||
* 【処理0】駐輪場マスタの情報を取得する
|
||||
* 【判断0】当該駐輪場実行タイミングチェック
|
||||
* 【処理2】定期更新対象者を取得する
|
||||
* 【判断2】利用者有無をチェック
|
||||
* 【処理3】対象者向けにメール送信、またはオペレーターキュー追加処理
|
||||
* 【処理4】バッチ処理ログを作成する
|
||||
*
|
||||
* @return array 処理結果
|
||||
*/
|
||||
public function executeReminderProcess(): array
|
||||
{
|
||||
$batchLogId = null;
|
||||
$processedParksCount = 0;
|
||||
$totalTargetUsers = 0;
|
||||
$mailSuccessCount = 0;
|
||||
$mailErrorCount = 0;
|
||||
$operatorQueueCount = 0;
|
||||
|
||||
try {
|
||||
// バッチ処理開始ログ作成
|
||||
$batchLog = BatchLog::createBatchLog(
|
||||
'shj3',
|
||||
BatchLog::STATUS_START,
|
||||
[],
|
||||
'SHJ-3 定期更新リマインダー処理開始'
|
||||
);
|
||||
$batchLogId = $batchLog->id;
|
||||
|
||||
Log::info('SHJ-3 定期更新リマインダー処理開始', [
|
||||
'batch_log_id' => $batchLogId
|
||||
]);
|
||||
|
||||
// 【処理0】駐輪場マスタの情報を取得する
|
||||
$parkList = $this->getParkMasterInfo();
|
||||
|
||||
if (empty($parkList)) {
|
||||
$message = '対象の駐輪場マスタが見つかりません';
|
||||
|
||||
$batchLog->update([
|
||||
'status' => BatchLog::STATUS_ERROR,
|
||||
'end_time' => now(),
|
||||
'message' => $message,
|
||||
'error_details' => $message,
|
||||
'error_count' => 1
|
||||
]);
|
||||
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => $message,
|
||||
'processed_parks_count' => 0,
|
||||
'total_target_users' => 0,
|
||||
'mail_success_count' => 0,
|
||||
'mail_error_count' => 0,
|
||||
'operator_queue_count' => 0,
|
||||
'batch_log_id' => $batchLogId
|
||||
];
|
||||
}
|
||||
|
||||
// 各駐輪場に対する処理ループ
|
||||
foreach ($parkList as $park) {
|
||||
Log::info('駐輪場処理開始', [
|
||||
'park_id' => $park->park_id,
|
||||
'park_name' => $park->park_name
|
||||
]);
|
||||
|
||||
// 【判断0】当該駐輪場実行タイミングチェック
|
||||
$timingCheckResult = $this->checkExecutionTiming($park);
|
||||
|
||||
if (!$timingCheckResult['should_execute']) {
|
||||
Log::info('実行タイミング対象外', [
|
||||
'park_id' => $park->park_id,
|
||||
'reason' => $timingCheckResult['reason']
|
||||
]);
|
||||
continue;
|
||||
}
|
||||
|
||||
$processedParksCount++;
|
||||
|
||||
// 【処理2】定期更新対象者を取得する
|
||||
$targetUsers = $this->getRegularUpdateTargetUsers($park->park_id);
|
||||
|
||||
// 【判断2】利用者有無をチェック
|
||||
if (empty($targetUsers)) {
|
||||
Log::info('利用者なし', [
|
||||
'park_id' => $park->park_id
|
||||
]);
|
||||
continue;
|
||||
}
|
||||
|
||||
$totalTargetUsers += count($targetUsers);
|
||||
|
||||
// 【処理3】対象者向けにメール送信、またはオペレーターキュー追加処理
|
||||
foreach ($targetUsers as $targetUser) {
|
||||
$processResult = $this->processTargetUser($targetUser);
|
||||
|
||||
if ($processResult['type'] === 'mail_success') {
|
||||
$mailSuccessCount++;
|
||||
} elseif ($processResult['type'] === 'mail_error') {
|
||||
$mailErrorCount++;
|
||||
} elseif ($processResult['type'] === 'operator_queue') {
|
||||
$operatorQueueCount++;
|
||||
}
|
||||
}
|
||||
|
||||
Log::info('駐輪場処理完了', [
|
||||
'park_id' => $park->park_id,
|
||||
'target_users_count' => count($targetUsers)
|
||||
]);
|
||||
}
|
||||
|
||||
// 【処理4】バッチ処理ログを作成する(SHJ-8呼び出し)
|
||||
$this->createShjBatchLog([
|
||||
'processed_parks_count' => $processedParksCount,
|
||||
'total_target_users' => $totalTargetUsers,
|
||||
'mail_success_count' => $mailSuccessCount,
|
||||
'mail_error_count' => $mailErrorCount,
|
||||
'operator_queue_count' => $operatorQueueCount
|
||||
]);
|
||||
|
||||
// バッチ処理完了ログ更新
|
||||
$batchLog->update([
|
||||
'status' => BatchLog::STATUS_SUCCESS,
|
||||
'end_time' => now(),
|
||||
'message' => 'SHJ-3 定期更新リマインダー処理正常完了',
|
||||
'success_count' => 1,
|
||||
'parameters' => [
|
||||
'processed_parks_count' => $processedParksCount,
|
||||
'total_target_users' => $totalTargetUsers,
|
||||
'mail_success_count' => $mailSuccessCount,
|
||||
'mail_error_count' => $mailErrorCount,
|
||||
'operator_queue_count' => $operatorQueueCount,
|
||||
'executed_at' => now()->toISOString()
|
||||
]
|
||||
]);
|
||||
|
||||
Log::info('SHJ-3 定期更新リマインダー処理完了', [
|
||||
'batch_log_id' => $batchLogId,
|
||||
'processed_parks_count' => $processedParksCount,
|
||||
'total_target_users' => $totalTargetUsers
|
||||
]);
|
||||
|
||||
return [
|
||||
'success' => true,
|
||||
'message' => 'SHJ-3 定期更新リマインダー処理が正常に完了しました',
|
||||
'processed_parks_count' => $processedParksCount,
|
||||
'total_target_users' => $totalTargetUsers,
|
||||
'mail_success_count' => $mailSuccessCount,
|
||||
'mail_error_count' => $mailErrorCount,
|
||||
'operator_queue_count' => $operatorQueueCount,
|
||||
'batch_log_id' => $batchLogId
|
||||
];
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$errorMessage = 'SHJ-3 定期更新リマインダー処理でエラーが発生: ' . $e->getMessage();
|
||||
|
||||
if (isset($batchLog) && $batchLog) {
|
||||
$batchLog->update([
|
||||
'status' => BatchLog::STATUS_ERROR,
|
||||
'end_time' => now(),
|
||||
'message' => $errorMessage,
|
||||
'error_details' => $e->getMessage(),
|
||||
'error_count' => 1
|
||||
]);
|
||||
}
|
||||
|
||||
Log::error('SHJ-3 定期更新リマインダー処理エラー', [
|
||||
'batch_log_id' => $batchLogId,
|
||||
'exception' => $e->getMessage(),
|
||||
'trace' => $e->getTraceAsString()
|
||||
]);
|
||||
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => $errorMessage,
|
||||
'details' => $e->getMessage(),
|
||||
'processed_parks_count' => $processedParksCount,
|
||||
'total_target_users' => $totalTargetUsers,
|
||||
'mail_success_count' => $mailSuccessCount,
|
||||
'mail_error_count' => $mailErrorCount,
|
||||
'operator_queue_count' => $operatorQueueCount,
|
||||
'batch_log_id' => $batchLogId
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 【処理0】駐輪場マスタの情報を取得する
|
||||
*
|
||||
* 仕様書に基づくSQLクエリ:
|
||||
* SELECT 駐輪場ID, 駐輪場名, 更新期間開始日, 更新期間開始時,
|
||||
* 更新期間終了日, 更新期間終了時, リマインダー種別, リマインダー時間
|
||||
* FROM 駐輪場マスタ
|
||||
* WHERE 閉設フラグ = 0
|
||||
* ORDER BY 駐輪場ふりがな asc
|
||||
*
|
||||
* @return array 駐輪場マスタ情報
|
||||
*/
|
||||
private function getParkMasterInfo(): array
|
||||
{
|
||||
try {
|
||||
$parkInfo = DB::table('park')
|
||||
->select([
|
||||
'park_id',
|
||||
'park_name',
|
||||
'renew_start_date',
|
||||
'renew_start_time',
|
||||
'renew_end_date',
|
||||
'renew_end_time',
|
||||
'reminder_type',
|
||||
'reminder_time'
|
||||
])
|
||||
->where('park_close_flag', 0)
|
||||
->orderBy('park_ruby', 'asc')
|
||||
->get()
|
||||
->toArray();
|
||||
|
||||
Log::info('駐輪場マスタ情報取得完了', [
|
||||
'park_count' => count($parkInfo)
|
||||
]);
|
||||
|
||||
return $parkInfo;
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('駐輪場マスタ情報取得エラー', [
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 【判断0】当該駐輪場実行タイミングチェック
|
||||
*
|
||||
* 仕様書に基づく複雑なリマインダー時期判定:
|
||||
* - パターンA: 月を跨らない場合(更新期間開始日 <= 更新期間終了日)
|
||||
* - パターンB: 月を跨る場合(更新期間開始日 > 更新期間終了日)
|
||||
* - リマインダー種別による実行判定
|
||||
*
|
||||
* @param object $park 駐輪場情報
|
||||
* @return array 実行タイミング判定結果
|
||||
*/
|
||||
private function checkExecutionTiming($park): array
|
||||
{
|
||||
try {
|
||||
$today = Carbon::now();
|
||||
$currentDate = $today->format('Y-m-d');
|
||||
|
||||
// 更新期間の日付を取得
|
||||
$startDate = Carbon::parse($park->renew_start_date);
|
||||
$endDate = Carbon::parse($park->renew_end_date);
|
||||
|
||||
Log::info('実行タイミングチェック開始', [
|
||||
'park_id' => $park->park_id,
|
||||
'current_date' => $currentDate,
|
||||
'start_date' => $startDate->format('Y-m-d'),
|
||||
'end_date' => $endDate->format('Y-m-d'),
|
||||
'reminder_type' => $park->reminder_type
|
||||
]);
|
||||
|
||||
// パターン判定: 月を跨るかどうか
|
||||
$isPatternA = $startDate->lte($endDate); // パターンA: 月を跨らない
|
||||
$isPatternB = !$isPatternA; // パターンB: 月を跨る
|
||||
|
||||
// 現在日付が更新期間内かチェック
|
||||
$isWithinUpdatePeriod = false;
|
||||
|
||||
if ($isPatternA) {
|
||||
// パターンA: 更新期間開始日 <= 現在日 <= 更新期間終了日
|
||||
$isWithinUpdatePeriod = $today->between($startDate, $endDate);
|
||||
} else {
|
||||
// パターンB: 月を跨る場合の判定
|
||||
// 現在日 >= 更新期間開始日 OR 現在日 <= 更新期間終了日
|
||||
$isWithinUpdatePeriod = $today->gte($startDate) || $today->lte($endDate);
|
||||
}
|
||||
|
||||
if (!$isWithinUpdatePeriod) {
|
||||
return [
|
||||
'should_execute' => false,
|
||||
'reason' => '更新期間外のため実行対象外',
|
||||
'pattern' => $isPatternA ? 'A' : 'B'
|
||||
];
|
||||
}
|
||||
|
||||
// リマインダー種別による実行判定
|
||||
$reminderExecutionResult = $this->checkReminderTiming($park, $today, $startDate, $endDate, $isPatternA);
|
||||
|
||||
Log::info('実行タイミングチェック完了', [
|
||||
'park_id' => $park->park_id,
|
||||
'should_execute' => $reminderExecutionResult['should_execute'],
|
||||
'pattern' => $isPatternA ? 'A' : 'B',
|
||||
'reminder_result' => $reminderExecutionResult
|
||||
]);
|
||||
|
||||
return $reminderExecutionResult;
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('実行タイミングチェックエラー', [
|
||||
'park_id' => $park->park_id,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* リマインダー時期の詳細判定
|
||||
*
|
||||
* 仕様書の複雑なリマインダー種別判定を実装
|
||||
* パターンA/Bに基づく詳細な日付計算ロジック
|
||||
*
|
||||
* @param object $park 駐輪場情報
|
||||
* @param Carbon $today 現在日
|
||||
* @param Carbon $startDate 更新期間開始日
|
||||
* @param Carbon $endDate 更新期間終了日
|
||||
* @param bool $isPatternA パターンAかどうか
|
||||
* @return array リマインダー実行判定結果
|
||||
*/
|
||||
private function checkReminderTiming($park, Carbon $today, Carbon $startDate, Carbon $endDate, bool $isPatternA): array
|
||||
{
|
||||
$reminderType = $park->reminder_type ?? 0;
|
||||
|
||||
// リマインダー種別 = 0 の場合は実行しない
|
||||
if ($reminderType == 0) {
|
||||
return [
|
||||
'should_execute' => false,
|
||||
'reason' => 'リマインダー種別=0のため実行対象外'
|
||||
];
|
||||
}
|
||||
|
||||
// 仕様書に基づく詳細なリマインダー時期判定
|
||||
$executionCheck = $this->performDetailedReminderCheck($park, $today, $startDate, $endDate, $isPatternA);
|
||||
|
||||
return [
|
||||
'should_execute' => $executionCheck['should_execute'],
|
||||
'reason' => $executionCheck['reason'],
|
||||
'reminder_type' => $reminderType,
|
||||
'pattern' => $isPatternA ? 'A' : 'B',
|
||||
'execution_details' => $executionCheck
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 仕様書に基づく詳細なリマインダー実行判定
|
||||
*
|
||||
* 複雑な条件分岐を含む実行フラグ判定処理
|
||||
* - パターンA/Bによる分岐
|
||||
* - リマインダー種別による日数計算
|
||||
* - 月跨ぎ処理の考慮
|
||||
*
|
||||
* @param object $park 駐輪場情報
|
||||
* @param Carbon $today 現在日
|
||||
* @param Carbon $startDate 更新期間開始日
|
||||
* @param Carbon $endDate 更新期間終了日
|
||||
* @param bool $isPatternA パターンAかどうか
|
||||
* @return array 実行判定詳細結果
|
||||
*/
|
||||
private function performDetailedReminderCheck($park, Carbon $today, Carbon $startDate, Carbon $endDate, bool $isPatternA): array
|
||||
{
|
||||
$reminderType = $park->reminder_type ?? 0;
|
||||
|
||||
// 内部変数 更新パターン判定
|
||||
$updatePattern = '';
|
||||
|
||||
if ($isPatternA) {
|
||||
// パターンA: 月を跨らない場合
|
||||
if ($startDate->lte($endDate)) {
|
||||
$updatePattern = 'A';
|
||||
} else {
|
||||
$updatePattern = 'B'; // 実際はパターンBになる
|
||||
}
|
||||
} else {
|
||||
// パターンB: 月を跨る場合
|
||||
$updatePattern = 'B';
|
||||
}
|
||||
|
||||
// 実行フラグ判定処理
|
||||
$executionFlag = $this->calculateExecutionFlag($today, $startDate, $endDate, $reminderType, $updatePattern);
|
||||
|
||||
Log::info('詳細リマインダー判定完了', [
|
||||
'park_id' => $park->park_id,
|
||||
'reminder_type' => $reminderType,
|
||||
'update_pattern' => $updatePattern,
|
||||
'execution_flag' => $executionFlag,
|
||||
'today' => $today->format('Y-m-d'),
|
||||
'start_date' => $startDate->format('Y-m-d'),
|
||||
'end_date' => $endDate->format('Y-m-d')
|
||||
]);
|
||||
|
||||
return [
|
||||
'should_execute' => $executionFlag['should_execute'],
|
||||
'reason' => $executionFlag['reason'],
|
||||
'update_pattern' => $updatePattern,
|
||||
'execution_details' => $executionFlag
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 実行フラグ計算処理
|
||||
*
|
||||
* 仕様書の複雑な分岐条件に基づく実行判定
|
||||
*
|
||||
* @param Carbon $today 現在日
|
||||
* @param Carbon $startDate 更新期間開始日
|
||||
* @param Carbon $endDate 更新期間終了日
|
||||
* @param int $reminderType リマインダー種別
|
||||
* @param string $updatePattern 更新パターン(A/B)
|
||||
* @return array 実行フラグ判定結果
|
||||
*/
|
||||
private function calculateExecutionFlag(Carbon $today, Carbon $startDate, Carbon $endDate, int $reminderType, string $updatePattern): array
|
||||
{
|
||||
// リマインダー種別による実行判定
|
||||
switch ($reminderType) {
|
||||
case 1: // -1日前
|
||||
return $this->checkReminderType1($today, $startDate, $endDate, $updatePattern);
|
||||
case 2: // -2日前
|
||||
return $this->checkReminderType2($today, $startDate, $endDate, $updatePattern);
|
||||
default:
|
||||
return [
|
||||
'should_execute' => false,
|
||||
'reason' => "未対応のリマインダー種別: {$reminderType}"
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* リマインダー種別=1(-1日前)の判定
|
||||
*
|
||||
* @param Carbon $today 現在日
|
||||
* @param Carbon $startDate 更新期間開始日
|
||||
* @param Carbon $endDate 更新期間終了日
|
||||
* @param string $updatePattern 更新パターン
|
||||
* @return array 判定結果
|
||||
*/
|
||||
private function checkReminderType1(Carbon $today, Carbon $startDate, Carbon $endDate, string $updatePattern): array
|
||||
{
|
||||
// 更新期間終了日の1日前が実行日
|
||||
$executionDate = $endDate->copy()->subDay();
|
||||
|
||||
if ($today->isSameDay($executionDate)) {
|
||||
return [
|
||||
'should_execute' => true,
|
||||
'reason' => '-1日前のリマインダー実行日',
|
||||
'execution_date' => $executionDate->format('Y-m-d')
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'should_execute' => false,
|
||||
'reason' => "リマインダー実行日({$executionDate->format('Y-m-d')})ではない(現在: {$today->format('Y-m-d')})",
|
||||
'execution_date' => $executionDate->format('Y-m-d')
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* リマインダー種別=2(-2日前)の判定
|
||||
*
|
||||
* @param Carbon $today 現在日
|
||||
* @param Carbon $startDate 更新期間開始日
|
||||
* @param Carbon $endDate 更新期間終了日
|
||||
* @param string $updatePattern 更新パターン
|
||||
* @return array 判定結果
|
||||
*/
|
||||
private function checkReminderType2(Carbon $today, Carbon $startDate, Carbon $endDate, string $updatePattern): array
|
||||
{
|
||||
// 更新期間終了日の2日前が実行日
|
||||
$executionDate = $endDate->copy()->subDays(2);
|
||||
|
||||
if ($today->isSameDay($executionDate)) {
|
||||
return [
|
||||
'should_execute' => true,
|
||||
'reason' => '-2日前のリマインダー実行日',
|
||||
'execution_date' => $executionDate->format('Y-m-d')
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'should_execute' => false,
|
||||
'reason' => "リマインダー実行日({$executionDate->format('Y-m-d')})ではない(現在: {$today->format('Y-m-d')})",
|
||||
'execution_date' => $executionDate->format('Y-m-d')
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 【処理2】定期更新対象者を取得する
|
||||
*
|
||||
* 仕様書に基づく複雑なSQLクエリ:
|
||||
* 定期契約マスタ T1 と 利用者マスタ T2 を結合して
|
||||
* 更新対象者の情報を取得する
|
||||
*
|
||||
* @param int $parkId 駐輪場ID
|
||||
* @return array 定期更新対象者情報
|
||||
*/
|
||||
private function getRegularUpdateTargetUsers(int $parkId): array
|
||||
{
|
||||
try {
|
||||
$currentDate = Carbon::now()->format('Y-m-d');
|
||||
|
||||
// 仕様書に記載されたSQLクエリに基づく対象者取得
|
||||
$targetUsers = DB::table('regular_contract as T1')
|
||||
->select([
|
||||
'T1.contract_id as 定期契約内ID',
|
||||
'T1.park_id as 駐輪場ID',
|
||||
'T2.user_id as 利用者ID',
|
||||
'T2.user_manual_regist_flag as 手動登録フラグ',
|
||||
'T2.user_primemail as メールアドレス',
|
||||
'T2.user_submail as 予備メールアドレス',
|
||||
'T2.user_name as 氏名',
|
||||
'T1.contract_periode as 有効期間E'
|
||||
])
|
||||
->join('user as T2', 'T1.user_id', '=', 'T2.user_id')
|
||||
->where('T1.park_id', $parkId)
|
||||
->where('T1.contract_periode', '<=', $currentDate) // 更新可能日チェック
|
||||
->where('T1.contract_cancel_flag', 0) // 解約フラグ = 0
|
||||
->where('T2.user_quit_flag', 0) // 退会フラグ = 0
|
||||
->where('T1.contract_flag', 1) // 承認フラグ = 1
|
||||
->whereNull('T1.contract_permission') // 更新済フラグ is null
|
||||
->get()
|
||||
->toArray();
|
||||
|
||||
Log::info('定期更新対象者取得完了', [
|
||||
'park_id' => $parkId,
|
||||
'target_users_count' => count($targetUsers)
|
||||
]);
|
||||
|
||||
return $targetUsers;
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('定期更新対象者取得エラー', [
|
||||
'park_id' => $parkId,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 【処理3】対象者の処理実行
|
||||
*
|
||||
* 手動登録フラグによって処理を分岐:
|
||||
* - = 0 (ウェブ申込み): SHJ-7メール送信を呼び出し
|
||||
* - その他: 内部変数のカウントアップ(オペレーターキュー処理)
|
||||
*
|
||||
* @param object $targetUser 対象者情報
|
||||
* @return array 処理結果
|
||||
*/
|
||||
private function processTargetUser($targetUser): array
|
||||
{
|
||||
try {
|
||||
$manualRegistFlag = $targetUser->手動登録フラグ ?? 1;
|
||||
|
||||
if ($manualRegistFlag == 0) {
|
||||
// ウェブ申込み: SHJ-7メール送信処理
|
||||
return $this->sendReminderMail($targetUser);
|
||||
} else {
|
||||
// その他: オペレーターキュー追加処理(内部変数カウントアップ)
|
||||
Log::info('オペレーターキュー対象者', [
|
||||
'user_id' => $targetUser->利用者ID,
|
||||
'contract_id' => $targetUser->定期契約内ID,
|
||||
'manual_regist_flag' => $manualRegistFlag
|
||||
]);
|
||||
|
||||
return [
|
||||
'type' => 'operator_queue',
|
||||
'success' => true,
|
||||
'message' => 'オペレーターキュー対象として処理'
|
||||
];
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('対象者処理エラー', [
|
||||
'user_id' => $targetUser->利用者ID ?? 'unknown',
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
|
||||
return [
|
||||
'type' => 'error',
|
||||
'success' => false,
|
||||
'message' => $e->getMessage()
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* リマインダーメール送信処理
|
||||
*
|
||||
* SHJ-7メール送信処理を呼び出し、使用プログラムID=200を使用
|
||||
*
|
||||
* @param object $targetUser 対象者情報
|
||||
* @return array 送信結果
|
||||
*/
|
||||
private function sendReminderMail($targetUser): array
|
||||
{
|
||||
try {
|
||||
$mailAddress = $targetUser->メールアドレス ?? '';
|
||||
$backupMailAddress = $targetUser->予備メールアドレス ?? '';
|
||||
$mailTemplateId = 200; // 使用プログラムID
|
||||
|
||||
Log::info('SHJ-7メール送信処理呼び出し', [
|
||||
'user_id' => $targetUser->利用者ID,
|
||||
'contract_id' => $targetUser->定期契約内ID,
|
||||
'mail_address' => $mailAddress,
|
||||
'backup_mail_address' => $backupMailAddress,
|
||||
'mail_template_id' => $mailTemplateId
|
||||
]);
|
||||
|
||||
// SHJ-7メール送信処理実行
|
||||
$mailResult = $this->mailSendService->executeMailSend(
|
||||
$mailAddress,
|
||||
$backupMailAddress,
|
||||
$mailTemplateId
|
||||
);
|
||||
|
||||
if ($mailResult['success']) {
|
||||
return [
|
||||
'type' => 'mail_success',
|
||||
'success' => true,
|
||||
'message' => 'メール送信成功',
|
||||
'mail_result' => $mailResult
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
'type' => 'mail_error',
|
||||
'success' => false,
|
||||
'message' => 'メール送信失敗: ' . $mailResult['message'],
|
||||
'mail_result' => $mailResult
|
||||
];
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('リマインダーメール送信エラー', [
|
||||
'user_id' => $targetUser->利用者ID ?? 'unknown',
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
|
||||
return [
|
||||
'type' => 'mail_error',
|
||||
'success' => false,
|
||||
'message' => 'メール送信エラー: ' . $e->getMessage()
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 【処理4】SHJ-8バッチ処理ログ作成
|
||||
*
|
||||
* 仕様書に基づくSHJ-8共通処理呼び出し
|
||||
*
|
||||
* @param array $statistics 処理統計情報
|
||||
* @return void
|
||||
*/
|
||||
private function createShjBatchLog(array $statistics): void
|
||||
{
|
||||
try {
|
||||
// 仕様書に基づくSHJ-8パラメータ設定
|
||||
$deviceId = 9999; // テスト用デバイスID(規格書では"-"だが、既存実装に合わせて9999使用)
|
||||
$processName = 'SHJ-3定期更新リマインダー';
|
||||
$jobName = 'success';
|
||||
$status = 'success';
|
||||
|
||||
// ステータスコメント生成
|
||||
$statusComment = "メール正常終了件数: {$statistics['mail_success_count']}" .
|
||||
" + メール異常終了件数: {$statistics['mail_error_count']}" .
|
||||
" + キュー登録正常終了件数: {$statistics['operator_queue_count']}";
|
||||
|
||||
$createdDate = now()->format('Y/m/d');
|
||||
$updatedDate = now()->format('Y/m/d');
|
||||
|
||||
Log::info('SHJ-8バッチ処理ログ作成', [
|
||||
'device_id' => $deviceId,
|
||||
'process_name' => $processName,
|
||||
'job_name' => $jobName,
|
||||
'status' => $status,
|
||||
'status_comment' => $statusComment,
|
||||
'created_date' => $createdDate,
|
||||
'updated_date' => $updatedDate
|
||||
]);
|
||||
|
||||
// 共通処理SHJ-8バッチ処理ログ作成を呼び出し
|
||||
// 注意: 実際の運用では外部コマンド呼び出しまたは専用サービス経由で実行
|
||||
BatchLog::createBatchLog(
|
||||
$processName,
|
||||
$status,
|
||||
[
|
||||
'device_id' => $deviceId,
|
||||
'job_name' => $jobName,
|
||||
'status_comment' => $statusComment,
|
||||
'statistics' => $statistics,
|
||||
'shj8_params' => [
|
||||
'device_id' => $deviceId,
|
||||
'process_name' => $processName,
|
||||
'job_name' => $jobName,
|
||||
'status' => $status,
|
||||
'created_date' => $createdDate,
|
||||
'updated_date' => $updatedDate
|
||||
]
|
||||
],
|
||||
$statusComment
|
||||
);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('SHJ-8バッチ処理ログ作成エラー', [
|
||||
'error' => $e->getMessage(),
|
||||
'statistics' => $statistics
|
||||
]);
|
||||
|
||||
// SHJ-8でエラーが発生してもメイン処理は継続
|
||||
// エラーログのみ出力
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user