From 8c0413157a87a8c59d90f0d8dd7ae7bcbe7b8c9c Mon Sep 17 00:00:00 2001 From: "go.unhi" Date: Thu, 23 Oct 2025 20:37:52 +0900 Subject: [PATCH] =?UTF-8?q?app/Services/ShjNineService.php=20=E3=82=92?= =?UTF-8?q?=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Services/ShjNineService.php | 595 -------------------------------- 1 file changed, 595 deletions(-) delete mode 100644 app/Services/ShjNineService.php diff --git a/app/Services/ShjNineService.php b/app/Services/ShjNineService.php deleted file mode 100644 index f5e0957..0000000 --- a/app/Services/ShjNineService.php +++ /dev/null @@ -1,595 +0,0 @@ -parkModel = $parkModel; - $this->contractModel = $contractModel; - $this->earningsSummaryModel = $earningsSummaryModel; - $this->psectionModel = $psectionModel; - $this->batchLogModel = $batchLogModel; - $this->operatorQueModel = $operatorQueModel; - } - - /** - * SHJ-9 売上集計処理メイン実行 - * - * 処理フロー: - * 【処理1】集計対象を設定する - * 【処理2】駐輪場マスタを取得する - * 【判断1】取得件数判定 - * 【処理3】車種区分毎に算出する - * 【判断2】取得判定 - * 【処理4】売上集計結果を削除→登録する - * 【処理5】オペレータキュー作成およびバッチ処理ログを作成する - * - * @param string $type 集計種別(daily/monthly/yearly) - * @param string $aggregationDate 集計対象日 - * @return array 処理結果 - */ - public function executeEarningsAggregation(string $type, string $aggregationDate): array - { - $batchLogId = null; - - try { - // 【処理1】集計対象を設定する - $aggregationTarget = $this->setAggregationTarget($type, $aggregationDate); - - // バッチ処理開始ログ作成 - $batchLog = BatchLog::createBatchLog( - 'shj9', - BatchLog::STATUS_START, - [ - 'type' => $type, - 'aggregation_date' => $aggregationDate, - 'aggregation_target' => $aggregationTarget - ], - "SHJ-9 売上集計処理開始 ({$type})" - ); - $batchLogId = $batchLog->id; - - Log::info('SHJ-9 売上集計処理開始', [ - 'batch_log_id' => $batchLogId, - 'type' => $type, - 'aggregation_date' => $aggregationDate, - 'aggregation_target' => $aggregationTarget - ]); - - // 【処理2】駐輪場マスタを取得する - $parkInfo = $this->getParkInformation(); - - // 【判断1】取得件数判定 - if (empty($parkInfo)) { - $message = '売上集計(' . $this->getTypeLabel($type) . '):駐輪場マスタが存在していません。'; - - // バッチログ更新 - $batchLog->update([ - 'status' => BatchLog::STATUS_WARNING, - 'end_time' => now(), - 'message' => $message, - 'success_count' => 1 // 処理は成功したが対象なし - ]); - - // 【処理5】オペレータキュー作成 - $this->createOperatorQueue($message, $batchLogId); - - return [ - 'success' => true, - 'message' => $message, - 'processed_parks' => 0, - 'summary_records' => 0, - 'batch_log_id' => $batchLogId - ]; - } - - // 【処理3】車種区分毎に算出する & 【処理4】売上集計結果を削除→登録する - $summaryRecords = 0; - $processedParks = 0; - - foreach ($parkInfo as $park) { - $parkSummaryRecords = $this->processEarningsForPark($park, $aggregationTarget, $type); - - if ($parkSummaryRecords > 0) { - $processedParks++; - $summaryRecords += $parkSummaryRecords; - } - } - - // 【判断2】取得判定 - if ($summaryRecords === 0) { - $message = '対象なしの結果を設定する(契約)'; - - // バッチログ更新 - $batchLog->update([ - 'status' => BatchLog::STATUS_WARNING, - 'end_time' => now(), - 'message' => $message, - 'success_count' => 1 - ]); - - // 【処理5】オペレータキュー作成 - $this->createOperatorQueue($message, $batchLogId); - - return [ - 'success' => true, - 'message' => $message, - 'processed_parks' => $processedParks, - 'summary_records' => 0, - 'batch_log_id' => $batchLogId - ]; - } - - // バッチ処理完了ログ更新 - $completionMessage = "SHJ-9 売上集計処理正常完了 ({$type}) - 駐輪場数: {$processedParks}, 集計レコード数: {$summaryRecords}"; - $batchLog->update([ - 'status' => BatchLog::STATUS_SUCCESS, - 'end_time' => now(), - 'message' => $completionMessage, - 'success_count' => 1 - ]); - - // 【処理5】オペレータキュー作成 - $this->createOperatorQueue($completionMessage, $batchLogId); - - Log::info('SHJ-9 売上集計処理完了', [ - 'batch_log_id' => $batchLogId, - 'processed_parks' => $processedParks, - 'summary_records' => $summaryRecords - ]); - - return [ - 'success' => true, - 'message' => 'SHJ-9 売上集計処理が正常に完了しました', - 'processed_parks' => $processedParks, - 'summary_records' => $summaryRecords, - 'batch_log_id' => $batchLogId - ]; - - } catch (\Exception $e) { - $errorMessage = 'SHJ-9 売上集計処理でエラーが発生: ' . $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-9 売上集計処理エラー', [ - 'batch_log_id' => $batchLogId, - 'exception' => $e->getMessage(), - 'trace' => $e->getTraceAsString() - ]); - - return [ - 'success' => false, - 'message' => $errorMessage, - 'details' => $e->getMessage(), - 'batch_log_id' => $batchLogId - ]; - } - } - - /** - * 【処理1】集計対象を設定する - * - * @param string $type 集計種別 - * @param string $aggregationDate 集計対象日 - * @return array 集計対象情報 - */ - private function setAggregationTarget(string $type, string $aggregationDate): array - { - $date = Carbon::parse($aggregationDate); - - switch ($type) { - case 'daily': - return [ - 'type' => 'daily', - 'start_date' => $date->format('Y-m-d'), - 'end_date' => $date->format('Y-m-d'), - 'summary_type' => '日次' - ]; - - case 'monthly': - return [ - 'type' => 'monthly', - 'start_date' => $date->startOfMonth()->format('Y-m-d'), - 'end_date' => $date->endOfMonth()->format('Y-m-d'), - 'summary_type' => '月次' - ]; - - case 'yearly': - return [ - 'type' => 'yearly', - 'start_date' => $date->startOfYear()->format('Y-m-d'), - 'end_date' => $date->endOfYear()->format('Y-m-d'), - 'summary_type' => '年次' - ]; - - default: - throw new \InvalidArgumentException("不正な集計種別: {$type}"); - } - } - - /** - * 【処理2】駐輪場マスタを取得する - * - * 仕様書のSQLクエリに基づく駐輪場情報取得 - * SELECT 駐輪場ID, 駐輪場名 - * FROM 駐輪場マスタ - * WHERE 閉設フラグ <> 1 - * ORDER BY 駐輪場ふりがな - * - * @return array 駐輪場情報 - */ - private function getParkInformation(): array - { - try { - $parkInfo = DB::table('park') - ->select(['park_id', 'park_name']) - ->where('park_close_flag', '<>', 1) - ->orderBy('park_ruby') - ->get() - ->toArray(); - - Log::info('駐輪場マスタ取得完了', [ - 'park_count' => count($parkInfo) - ]); - - return $parkInfo; - - } catch (\Exception $e) { - Log::error('駐輪場マスタ取得エラー', [ - 'error' => $e->getMessage() - ]); - - throw $e; - } - } - - /** - * 駐輪場毎の売上集計処理 - * - * @param object $park 駐輪場情報 - * @param array $aggregationTarget 集計対象 - * @param string $type 集計種別 - * @return int 作成された集計レコード数 - */ - private function processEarningsForPark($park, array $aggregationTarget, string $type): int - { - try { - // 【処理4】既存の売上集計結果を削除 - $this->deleteExistingSummary($park->park_id, $aggregationTarget); - - // 【処理3】車種区分毎に算出する - $psections = $this->getPsectionInformation(); - $summaryRecords = 0; - - foreach ($psections as $psection) { - $earningsData = $this->calculateEarningsForPsection( - $park->park_id, - $psection->psection_id, - $aggregationTarget - ); - - if ($this->hasEarningsData($earningsData)) { - // 売上集計結果を登録 - $this->createEarningsSummary($park, $psection, $aggregationTarget, $earningsData, $type); - $summaryRecords++; - } - } - - Log::info('駐輪場売上集計完了', [ - 'park_id' => $park->park_id, - 'park_name' => $park->park_name, - 'summary_records' => $summaryRecords - ]); - - return $summaryRecords; - - } catch (\Exception $e) { - Log::error('駐輪場売上集計エラー', [ - 'park_id' => $park->park_id, - 'error' => $e->getMessage() - ]); - - throw $e; - } - } - - /** - * 車種区分情報取得 - * - * @return array 車種区分情報 - */ - private function getPsectionInformation(): array - { - return DB::table('psection') - ->select(['psection_id', 'psection_subject']) - ->get() - ->toArray(); - } - - /** - * 【処理3】車種区分毎に売上を算出する - * - * 4つの項目を計算: - * ①売上・件数 - * ②一時金売上 - * ③解約返戻金 - * ④再発行金額・件数 - * - * @param int $parkId 駐輪場ID - * @param int $psectionId 車種区分ID - * @param array $aggregationTarget 集計対象 - * @return array 売上データ - */ - private function calculateEarningsForPsection(int $parkId, int $psectionId, array $aggregationTarget): array - { - $startDate = $aggregationTarget['start_date']; - $endDate = $aggregationTarget['end_date']; - - // ①売上・件数(billing_amount) - $salesData = DB::table('regular_contract') - ->select([ - DB::raw('COUNT(*) as sales_count'), - DB::raw('COALESCE(SUM(billing_amount), 0) as sales_amount') - ]) - ->where('park_id', $parkId) - ->where('psection_id', $psectionId) - ->where('contract_flag', 1) - ->whereBetween('contract_payment_day', [$startDate, $endDate]) - ->whereNull('contract_cancelday') - ->first(); - - // ②一時金売上(contract_money) - $temporaryData = DB::table('regular_contract') - ->select([ - DB::raw('COUNT(*) as temporary_count'), - DB::raw('COALESCE(SUM(contract_money), 0) as temporary_amount') - ]) - ->where('park_id', $parkId) - ->where('psection_id', $psectionId) - ->where('contract_flag', 1) - ->whereBetween('contract_payment_day', [$startDate, $endDate]) - ->whereNotNull('contract_money') - ->where('contract_money', '>', 0) - ->first(); - - // ③解約返戻金(refunds) - $refundData = DB::table('regular_contract') - ->select([ - DB::raw('COUNT(*) as refund_count'), - DB::raw('COALESCE(SUM(refunds), 0) as refund_amount') - ]) - ->where('park_id', $parkId) - ->where('psection_id', $psectionId) - ->whereBetween('contract_cancelday', [$startDate, $endDate]) - ->whereNotNull('refunds') - ->where('refunds', '>', 0) - ->first(); - - // ④再発行金額・件数(seal_reissue_request) - $reissueData = DB::table('regular_contract') - ->select([ - DB::raw('COUNT(*) as reissue_count'), - DB::raw('COALESCE(SUM(contract_seal_issue), 0) as reissue_amount') - ]) - ->where('park_id', $parkId) - ->where('psection_id', $psectionId) - ->where('seal_reissue_request', 1) - ->whereBetween('updated_at', [$startDate, $endDate]) - ->first(); - - return [ - 'sales_count' => $salesData->sales_count ?? 0, - 'sales_amount' => $salesData->sales_amount ?? 0, - 'temporary_count' => $temporaryData->temporary_count ?? 0, - 'temporary_amount' => $temporaryData->temporary_amount ?? 0, - 'refund_count' => $refundData->refund_count ?? 0, - 'refund_amount' => $refundData->refund_amount ?? 0, - 'reissue_count' => $reissueData->reissue_count ?? 0, - 'reissue_amount' => $reissueData->reissue_amount ?? 0 - ]; - } - - /** - * 売上データの存在チェック - * - * @param array $earningsData 売上データ - * @return bool データが存在するかどうか - */ - private function hasEarningsData(array $earningsData): bool - { - return $earningsData['sales_count'] > 0 || - $earningsData['temporary_count'] > 0 || - $earningsData['refund_count'] > 0 || - $earningsData['reissue_count'] > 0; - } - - /** - * 【処理4】既存の売上集計結果を削除 - * - * @param int $parkId 駐輪場ID - * @param array $aggregationTarget 集計対象 - * @return void - */ - private function deleteExistingSummary(int $parkId, array $aggregationTarget): void - { - DB::table('earnings_summary') - ->where('park_id', $parkId) - ->where('summary_start_date', $aggregationTarget['start_date']) - ->where('summary_end_date', $aggregationTarget['end_date']) - ->delete(); - } - - /** - * 売上集計結果を登録 - * - * @param object $park 駐輪場情報 - * @param object $psection 車種区分情報 - * @param array $aggregationTarget 集計対象 - * @param array $earningsData 売上データ - * @param string $type 集計種別 - * @return void - */ - private function createEarningsSummary($park, $psection, array $aggregationTarget, array $earningsData, string $type): void - { - DB::table('earnings_summary')->insert([ - 'park_id' => $park->park_id, - 'summary_type' => $aggregationTarget['summary_type'], - 'summary_start_date' => $aggregationTarget['start_date'], - 'summary_end_date' => $aggregationTarget['end_date'], - 'earnings_date' => $aggregationTarget['end_date'], // 集計日として終了日を使用 - 'psection_id' => $psection->psection_id, - 'usertype_subject1' => $psection->psection_subject, - 'regular_new_count' => $earningsData['sales_count'], - 'regular_new_amount' => $earningsData['sales_amount'], - 'turnsum' => $earningsData['temporary_amount'], - 'turnsum_count' => $earningsData['temporary_count'], - 'refunds' => $earningsData['refund_amount'], - 'reissue_count' => $earningsData['reissue_count'], - 'reissue_amount' => $earningsData['reissue_amount'], - 'summary_note' => "SHJ-9 {$type} 売上集計結果", - 'created_at' => now(), - 'updated_at' => now(), - 'operator_id' => 0 // システム処理 - ]); - } - - /** - * 【処理5】オペレータキュー作成 - * - * @param string $message メッセージ - * @param int $batchLogId バッチログID - * @return void - */ - private function createOperatorQueue(string $message, int $batchLogId): void - { - try { - DB::table('operator_que')->insert([ - 'que_class' => 9, // SHJ-9用のクラス - 'user_id' => null, - 'contract_id' => null, - 'park_id' => null, - 'que_comment' => $message, - 'que_status' => 1, // 完了 - 'que_status_comment' => 'バッチ処理完了', - 'work_instructions' => "SHJ-9売上集計処理 BatchLogID: {$batchLogId}", - 'created_at' => now(), - 'updated_at' => now() - ]); - - Log::info('オペレータキュー作成完了', [ - 'batch_log_id' => $batchLogId, - 'message' => $message - ]); - - } catch (\Exception $e) { - Log::error('オペレータキュー作成エラー', [ - 'batch_log_id' => $batchLogId, - 'error' => $e->getMessage() - ]); - } - } - - /** - * 集計種別のラベル取得 - * - * @param string $type 集計種別 - * @return string ラベル - */ - private function getTypeLabel(string $type): string - { - switch ($type) { - case 'daily': - return '日次'; - case 'monthly': - return '月次'; - case 'yearly': - return '年次'; - default: - return $type; - } - } -}