so-manager-dev.com/app/Console/Commands/ShjTenCommand.php
2025-09-19 19:01:21 +09:00

237 lines
8.1 KiB
PHP
Raw Permalink 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\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use App\Services\ShjTenService;
/**
* SHJ-10 売上集計処理コマンド
*
* 駐輪場の売上データを財政年度ベースで年次・月次集計する処理を実行する
* 4月開始の財政年度期間で計算するバックグラウンドバッチ処理
*/
class ShjTenCommand extends Command
{
/**
* コンソールコマンドの名前とシグネチャ
*
* 引数:
* - type: 集計種別 (yearly/monthly) (必須)
* - target: 集計対象 (必須)
* - yearly: 年度 (例: 2019)
* - monthly: 年月 (例: 2019/01)
*
* @var string
*/
protected $signature = 'shj:10 {type : 集計種別(yearly/monthly)} {target : 集計対象(yearly:年度, monthly:年月)}';
/**
* コンソールコマンドの説明
*
* @var string
*/
protected $description = 'SHJ-10 売上集計処理 - 財政年度ベース年次/月次売上データ集計を実行';
/**
* SHJ-10サービスクラス
*
* @var ShjTenService
*/
protected $shjTenService;
/**
* コンストラクタ
*
* @param ShjTenService $shjTenService
*/
public function __construct(ShjTenService $shjTenService)
{
parent::__construct();
$this->shjTenService = $shjTenService;
}
/**
* コンソールコマンドを実行
*
* 処理フロー:
* 1. パラメータ取得と検証
* 2. 財政年度期間設定
* 3. 売上集計処理実行
* 4. バッチログ作成
* 5. 処理結果返却
*
* @return int
*/
public function handle()
{
try {
// 開始ログ出力
$startTime = now();
$this->info('SHJ-10 売上集計処理を開始します。');
// 引数取得
$type = $this->argument('type');
$target = $this->argument('target');
Log::info('SHJ-10 売上集計処理開始', [
'start_time' => $startTime,
'type' => $type,
'target' => $target
]);
// パラメータ検証
if (!$this->validateParameters($type, $target)) {
$this->error('パラメータが不正です。');
return self::FAILURE;
}
// 財政年度期間設定
$fiscalPeriod = $this->determineFiscalPeriod($type, $target);
$this->info("集計種別: {$type}");
$this->info("集計対象: {$target}");
$this->info("財政期間: {$fiscalPeriod['start_date']} {$fiscalPeriod['end_date']}");
// SHJ-10処理実行
$result = $this->shjTenService->executeFiscalEarningsAggregation($type, $target, $fiscalPeriod);
// 処理結果確認
if ($result['success']) {
$endTime = now();
$this->info('SHJ-10 売上集計処理が正常に完了しました。');
$this->info("処理時間: {$startTime->diffInSeconds($endTime)}");
$this->info("処理結果: 駐輪場数 {$result['processed_parks']}, 集計レコード数 {$result['summary_records']}");
Log::info('SHJ-10 売上集計処理完了', [
'end_time' => $endTime,
'duration_seconds' => $startTime->diffInSeconds($endTime),
'result' => $result
]);
return self::SUCCESS;
} else {
$this->error('SHJ-10 売上集計処理でエラーが発生しました: ' . $result['message']);
Log::error('SHJ-10 売上集計処理エラー', [
'error' => $result['message'],
'details' => $result['details'] ?? null
]);
return self::FAILURE;
}
} catch (\Exception $e) {
$this->error('SHJ-10 売上集計処理で予期しないエラーが発生しました: ' . $e->getMessage());
Log::error('SHJ-10 売上集計処理例外エラー', [
'exception' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
return self::FAILURE;
}
}
/**
* パラメータの妥当性を検証
*
* @param string $type 集計種別
* @param string $target 集計対象
* @return bool 検証結果
*/
private function validateParameters(string $type, string $target): bool
{
// 集計種別チェック
$allowedTypes = ['yearly', 'monthly'];
if (!in_array($type, $allowedTypes)) {
$this->error('集計種別は yearly, monthly のいずれかを指定してください。');
return false;
}
// 集計対象形式チェック
if ($type === 'yearly') {
// 年度形式チェック (例: 2019)
if (!preg_match('/^\d{4}$/', $target)) {
$this->error('年次集計の場合、年度を4桁の数字で指定してください。(例: 2019)');
return false;
}
} elseif ($type === 'monthly') {
// 年月形式チェック (例: 2019/01)
if (!preg_match('/^\d{4}\/\d{2}$/', $target)) {
$this->error('月次集計の場合、年月をYYYY/MM形式で指定してください。(例: 2019/01)');
return false;
}
// 月の範囲チェック (01-12)
$parts = explode('/', $target);
$month = (int)$parts[1];
if ($month < 1 || $month > 12) {
$this->error('月は01から12までの範囲で指定してください。');
return false;
}
}
return true;
}
/**
* 財政年度期間を決定
*
* 財政年度は4月開始Config設定可能
* - yearly 2019: 2019年4月1日 2020年3月31日
* - monthly 2019/01: 2019年1月1日 2019年1月31日
*
* @param string $type 集計種別
* @param string $target 集計対象
* @return array 財政期間情報
*/
private function determineFiscalPeriod(string $type, string $target): array
{
$fiscalStartMonth = 4; // 財政年度開始月4月
if ($type === 'yearly') {
$year = (int)$target;
// 財政年度期間計算
$startDate = sprintf('%04d-%02d-01', $year, $fiscalStartMonth);
$endDate = sprintf('%04d-%02d-%02d', $year + 1, $fiscalStartMonth - 1,
date('t', strtotime(sprintf('%04d-%02d-01', $year + 1, $fiscalStartMonth - 1))));
return [
'type' => 'yearly',
'fiscal_year' => $year,
'start_date' => $startDate,
'end_date' => $endDate,
'summary_type' => 1, // 年次
'target_label' => "{$year}年度"
];
} elseif ($type === 'monthly') {
$parts = explode('/', $target);
$year = (int)$parts[0];
$month = (int)$parts[1];
// 指定月の期間計算
$startDate = sprintf('%04d-%02d-01', $year, $month);
$endDate = sprintf('%04d-%02d-%02d', $year, $month,
date('t', strtotime($startDate)));
// 該当する財政年度を計算
$fiscalYear = $month >= $fiscalStartMonth ? $year : $year - 1;
return [
'type' => 'monthly',
'fiscal_year' => $fiscalYear,
'target_year' => $year,
'target_month' => $month,
'start_date' => $startDate,
'end_date' => $endDate,
'summary_type' => 2, // 月次
'target_label' => "{$year}{$month}"
];
}
throw new \InvalidArgumentException("不正な集計種別: {$type}");
}
}