shjNineService = $shjNineService; } /** * コンソールコマンドを実行 * * 処理フロー: * 1. パラメータ取得と検証 * 2. 集計対象日設定 * 3. 売上集計処理実行 * 4. バッチログ作成 * 5. 処理結果返却 * * @return int */ public function handle() { try { // 開始ログ出力 $startTime = now(); $this->info('SHJ-9 売上集計処理を開始します。'); // 引数取得 $type = $this->argument('type'); $targetDate = $this->argument('target_date'); Log::info('SHJ-9 売上集計処理開始', [ 'start_time' => $startTime, 'type' => $type, 'target_date' => $targetDate ]); // パラメータ検証 if (!$this->validateParameters($type, $targetDate)) { $this->error('パラメータが不正です。'); return self::FAILURE; } // 集計対象日設定 $aggregationDate = $this->determineAggregationDate($type, $targetDate); $this->info("集計種別: {$type}"); $this->info("集計対象日: {$aggregationDate}"); // SHJ-9処理実行 $result = $this->shjNineService->executeEarningsAggregation($type, $aggregationDate); // 処理結果確認 if ($result['success']) { $endTime = now(); $this->info('SHJ-9 売上集計処理が正常に完了しました。'); $this->info("処理時間: {$startTime->diffInSeconds($endTime)}秒"); $this->info("処理結果: 駐輪場数 {$result['processed_parks']}, 集計レコード数 {$result['summary_records']}"); Log::info('SHJ-9 売上集計処理完了', [ 'end_time' => $endTime, 'duration_seconds' => $startTime->diffInSeconds($endTime), 'result' => $result ]); return self::SUCCESS; } else { $this->error('SHJ-9 売上集計処理でエラーが発生しました: ' . $result['message']); Log::error('SHJ-9 売上集計処理エラー', [ 'error' => $result['message'], 'details' => $result['details'] ?? null ]); return self::FAILURE; } } catch (\Exception $e) { $this->error('SHJ-9 売上集計処理で予期しないエラーが発生しました: ' . $e->getMessage()); Log::error('SHJ-9 売上集計処理例外エラー', [ 'exception' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); return self::FAILURE; } } /** * パラメータの妥当性を検証 * * @param string $type 集計種別 * @param string|null $targetDate 対象日 * @return bool 検証結果 */ private function validateParameters(string $type, ?string $targetDate): bool { // 集計種別チェック $allowedTypes = ['daily', 'monthly', 'yearly']; if (!in_array($type, $allowedTypes)) { $this->error('集計種別は daily, monthly, yearly のいずれかを指定してください。'); return false; } // 対象日形式チェック(指定されている場合) if ($targetDate && !$this->isValidDateFormat($targetDate)) { $this->error('対象日の形式が正しくありません(YYYY-MM-DD形式で指定してください)。'); return false; } return true; } /** * 集計対象日を決定 * * @param string $type 集計種別 * @param string|null $targetDate 指定日 * @return string 集計対象日 */ private function determineAggregationDate(string $type, ?string $targetDate): string { if ($targetDate) { return $targetDate; } // パラメータ指定がない場合のデフォルト設定 switch ($type) { case 'daily': // 日次:昨日(本日の1日前) return now()->subDay()->format('Y-m-d'); case 'monthly': // 月次:前月の最終日 return now()->subMonth()->endOfMonth()->format('Y-m-d'); case 'yearly': // 年次:前年の最終日 return now()->subYear()->endOfYear()->format('Y-m-d'); default: return now()->subDay()->format('Y-m-d'); } } /** * 日付形式の検証 * * @param string $date 日付文字列 * @return bool 有効な日付形式かどうか */ private function isValidDateFormat(string $date): bool { // YYYY-MM-DD形式の正規表現チェック if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) { return false; } // 実際の日付として有効かチェック $dateParts = explode('-', $date); return checkdate((int)$dateParts[1], (int)$dateParts[2], (int)$dateParts[0]); } }