app/Console/Commands/ShjFourBCheckCommand.php を削除
Some checks failed
Deploy main / deploy (push) Has been cancelled
Some checks failed
Deploy main / deploy (push) Has been cancelled
This commit is contained in:
parent
7be5e66430
commit
17cbd3c065
@ -1,317 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use App\Models\SettlementTransaction;
|
||||
use App\Models\Batch\BatchLog;
|
||||
use App\Jobs\ProcessSettlementJob;
|
||||
use App\Services\ShjFourBService;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Queue;
|
||||
use Carbon\Carbon;
|
||||
|
||||
/**
|
||||
* SHJ-4B チェックコマンド
|
||||
*
|
||||
* 未処理の決済トランザクションを検索し、ProcessSettlementJobをディスパッチする兜底処理
|
||||
*
|
||||
* 実行方法:
|
||||
* php artisan shj4b:check
|
||||
* php artisan shj4b:check --dry-run # 実際の処理は行わず、対象のみ表示
|
||||
* php artisan shj4b:check --limit=50 # 処理件数制限
|
||||
*
|
||||
* Cron設定例(10分毎実行):
|
||||
* 0,10,20,30,40,50 * * * * cd /path/to/project && php artisan shj4b:check > /dev/null 2>&1
|
||||
*/
|
||||
class ShjFourBCheckCommand extends Command
|
||||
{
|
||||
/**
|
||||
* コマンド名と説明
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'shj4b:check
|
||||
{--dry-run : 実際の処理を行わず対象のみ表示}
|
||||
{--limit=100 : 処理する最大件数}
|
||||
{--hours=24 : 指定時間以内の決済のみ対象}';
|
||||
|
||||
/**
|
||||
* コマンドの説明
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'SHJ-4B 兜底チェック - 未処理の決済トランザクションを検索してProcessSettlementJobをディスパッチ';
|
||||
|
||||
/**
|
||||
* SHJ-4B サービス
|
||||
*
|
||||
* @var ShjFourBService
|
||||
*/
|
||||
protected $shjFourBService;
|
||||
|
||||
/**
|
||||
* コンストラクタ
|
||||
*/
|
||||
public function __construct(ShjFourBService $shjFourBService)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->shjFourBService = $shjFourBService;
|
||||
}
|
||||
|
||||
/**
|
||||
* コマンド実行
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$startTime = now();
|
||||
$isDryRun = $this->option('dry-run');
|
||||
$limit = (int) $this->option('limit');
|
||||
$hours = (int) $this->option('hours');
|
||||
|
||||
$this->info("SHJ-4B チェックコマンド開始");
|
||||
$this->info("実行モード: " . ($isDryRun ? "ドライラン(実際の処理なし)" : "本実行"));
|
||||
$this->info("処理制限: {$limit}件");
|
||||
$this->info("対象期間: {$hours}時間以内");
|
||||
|
||||
// バッチログ作成
|
||||
$batch = BatchLog::createBatchLog(
|
||||
'shj4b_check',
|
||||
BatchLog::STATUS_START,
|
||||
[
|
||||
'command' => 'shj4b:check',
|
||||
'options' => [
|
||||
'dry_run' => $isDryRun,
|
||||
'limit' => $limit,
|
||||
'hours' => $hours,
|
||||
],
|
||||
'start_time' => $startTime,
|
||||
],
|
||||
'SHJ-4B チェックコマンド開始'
|
||||
);
|
||||
|
||||
try {
|
||||
// 未処理の決済トランザクション取得
|
||||
$unprocessedSettlements = $this->getUnprocessedSettlements($hours, $limit);
|
||||
|
||||
$this->info("未処理決済トランザクション: " . $unprocessedSettlements->count() . "件");
|
||||
|
||||
if ($unprocessedSettlements->isEmpty()) {
|
||||
$this->info("処理対象なし");
|
||||
|
||||
$batch->update([
|
||||
'status' => BatchLog::STATUS_SUCCESS,
|
||||
'end_time' => now(),
|
||||
'message' => 'SHJ-4B チェック完了 - 処理対象なし',
|
||||
'success_count' => 0,
|
||||
]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 対象一覧表示
|
||||
$this->displayTargets($unprocessedSettlements);
|
||||
|
||||
if ($isDryRun) {
|
||||
$this->info("ドライランモードのため、実際の処理はスキップします");
|
||||
|
||||
$batch->update([
|
||||
'status' => BatchLog::STATUS_SUCCESS,
|
||||
'end_time' => now(),
|
||||
'message' => 'SHJ-4B チェック完了 - ドライラン',
|
||||
'success_count' => 0,
|
||||
'parameters' => json_encode(['targets' => $unprocessedSettlements->pluck('settlement_transaction_id')->toArray()]),
|
||||
]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 実際の処理実行
|
||||
$processed = $this->processSettlements($unprocessedSettlements);
|
||||
|
||||
$this->info("処理完了: {$processed['success']}件成功, {$processed['failed']}件失敗");
|
||||
|
||||
$batch->update([
|
||||
'status' => $processed['failed'] > 0 ? BatchLog::STATUS_ERROR : BatchLog::STATUS_SUCCESS,
|
||||
'end_time' => now(),
|
||||
'message' => "SHJ-4B チェック完了 - 成功:{$processed['success']}件, 失敗:{$processed['failed']}件",
|
||||
'success_count' => $processed['success'],
|
||||
'error_count' => $processed['failed'],
|
||||
'parameters' => json_encode($processed),
|
||||
]);
|
||||
|
||||
return $processed['failed'] > 0 ? 1 : 0;
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
$this->error("SHJ-4B チェック処理でエラーが発生しました: " . $e->getMessage());
|
||||
Log::error('SHJ-4B チェックコマンドエラー', [
|
||||
'error' => $e->getMessage(),
|
||||
'trace' => $e->getTraceAsString(),
|
||||
]);
|
||||
|
||||
$batch->update([
|
||||
'status' => BatchLog::STATUS_ERROR,
|
||||
'end_time' => now(),
|
||||
'message' => 'SHJ-4B チェック失敗: ' . $e->getMessage(),
|
||||
'error_details' => $e->getTraceAsString(),
|
||||
'error_count' => 1,
|
||||
]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 未処理の決済トランザクション取得
|
||||
*
|
||||
* @param int $hours
|
||||
* @param int $limit
|
||||
* @return \Illuminate\Database\Eloquent\Collection
|
||||
*/
|
||||
private function getUnprocessedSettlements(int $hours, int $limit)
|
||||
{
|
||||
$cutoffTime = Carbon::now()->subHours($hours);
|
||||
|
||||
// 条件:
|
||||
// 1. 指定時間以内に作成された
|
||||
// 2. contract_payment_numberがnullでない
|
||||
// 3. まだregular_contractのsettlement_transaction_idに関連付けられていない
|
||||
// 4. ProcessSettlementJobが実行されていない(batch_logで確認)
|
||||
$query = SettlementTransaction::where('created_at', '>=', $cutoffTime)
|
||||
->whereNotNull('contract_payment_number')
|
||||
->whereNotNull('pay_date')
|
||||
->whereNotNull('settlement_amount')
|
||||
->orderBy('created_at', 'asc');
|
||||
|
||||
$settlements = $query->limit($limit)->get();
|
||||
|
||||
// 既に処理済みのものを除外
|
||||
$unprocessed = $settlements->filter(function ($settlement) {
|
||||
return !$this->isAlreadyProcessed($settlement);
|
||||
});
|
||||
|
||||
return $unprocessed;
|
||||
}
|
||||
|
||||
/**
|
||||
* 既に処理済みかチェック
|
||||
*
|
||||
* @param SettlementTransaction $settlement
|
||||
* @return bool
|
||||
*/
|
||||
private function isAlreadyProcessed(SettlementTransaction $settlement): bool
|
||||
{
|
||||
// 1. regular_contractの同一contract_payment_numberが既に処理済みかチェック
|
||||
$linkedContract = DB::table('regular_contract')
|
||||
->where('contract_payment_number', $settlement->contract_payment_number)
|
||||
->whereNotNull('contract_payment_day')
|
||||
->exists();
|
||||
|
||||
if ($linkedContract) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 2. batch_logで処理完了記録があるかチェック
|
||||
$processedInBatch = BatchLog::where('process_name', 'shj4b')
|
||||
->where('status', BatchLog::STATUS_SUCCESS)
|
||||
->where('parameters', 'like', '%"settlement_transaction_id":' . $settlement->settlement_transaction_id . '%')
|
||||
->exists();
|
||||
|
||||
if ($processedInBatch) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 3. 現在キューに入っているかチェック(簡易版)
|
||||
// 注: より正確にはRedis/DBキューの内容を確認する必要がある
|
||||
$recentJobDispatched = BatchLog::where('process_name', 'shj4b')
|
||||
->where('parameters', 'like', '%"settlement_transaction_id":' . $settlement->settlement_transaction_id . '%')
|
||||
->where('created_at', '>=', Carbon::now()->subHours(1))
|
||||
->exists();
|
||||
|
||||
return $recentJobDispatched;
|
||||
}
|
||||
|
||||
/**
|
||||
* 対象一覧表示
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Collection $settlements
|
||||
*/
|
||||
private function displayTargets($settlements)
|
||||
{
|
||||
$this->info("対象の決済トランザクション:");
|
||||
$this->table(
|
||||
['ID', '契約支払番号', '決済金額', '支払日', '作成日時'],
|
||||
$settlements->map(function ($settlement) {
|
||||
return [
|
||||
$settlement->settlement_transaction_id,
|
||||
$settlement->contract_payment_number,
|
||||
number_format($settlement->settlement_amount) . '円',
|
||||
Carbon::parse($settlement->pay_date)->format('Y-m-d H:i:s'),
|
||||
$settlement->created_at->format('Y-m-d H:i:s'),
|
||||
];
|
||||
})->toArray()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 決済処理実行
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Collection $settlements
|
||||
* @return array
|
||||
*/
|
||||
private function processSettlements($settlements): array
|
||||
{
|
||||
$success = 0;
|
||||
$failed = 0;
|
||||
$results = [];
|
||||
|
||||
foreach ($settlements as $settlement) {
|
||||
try {
|
||||
$this->info("処理中: 決済トランザクションID {$settlement->settlement_transaction_id}");
|
||||
|
||||
// ProcessSettlementJobをディスパッチ
|
||||
ProcessSettlementJob::dispatch(
|
||||
$settlement->settlement_transaction_id,
|
||||
[
|
||||
'source' => 'shj4b_check_command',
|
||||
'triggered_at' => now()->toISOString(),
|
||||
]
|
||||
);
|
||||
|
||||
$success++;
|
||||
$results[] = [
|
||||
'settlement_transaction_id' => $settlement->settlement_transaction_id,
|
||||
'status' => 'dispatched',
|
||||
'message' => 'ProcessSettlementJobディスパッチ成功',
|
||||
];
|
||||
|
||||
$this->info("✓ 成功: {$settlement->settlement_transaction_id}");
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
$failed++;
|
||||
$results[] = [
|
||||
'settlement_transaction_id' => $settlement->settlement_transaction_id,
|
||||
'status' => 'failed',
|
||||
'error' => $e->getMessage(),
|
||||
];
|
||||
|
||||
$this->error("✗ 失敗: {$settlement->settlement_transaction_id} - {$e->getMessage()}");
|
||||
|
||||
Log::error('SHJ-4B チェック 個別処理失敗', [
|
||||
'settlement_transaction_id' => $settlement->settlement_transaction_id,
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'success' => $success,
|
||||
'failed' => $failed,
|
||||
'results' => $results,
|
||||
'total' => $settlements->count(),
|
||||
];
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user