diff --git a/app/Http/Controllers/Admin/PeriodicalController.php b/app/Http/Controllers/Admin/PeriodicalController.php index 37b81e5..d77cf6b 100644 --- a/app/Http/Controllers/Admin/PeriodicalController.php +++ b/app/Http/Controllers/Admin/PeriodicalController.php @@ -10,13 +10,13 @@ class PeriodicalController extends Controller // 画面 public function list(Request $request) { - // Bladeで使うカラム名(id, name)で取得 - $parks = DB::table('park') - ->select('park_id', 'park_name') - ->orderBy('park_name') + $parks = DB::table('regular_contract') + ->join('park', 'regular_contract.park_id', '=', 'park.park_id') + ->select('park.park_id', 'park.park_name') + ->distinct() + ->orderBy('park.park_name') ->get(); - // 必要なら選択中のpark_idも渡す $selectedParkId = $request->input('park_id', ''); return view('admin.periodical.list', compact('parks', 'selectedParkId')); @@ -27,73 +27,365 @@ class PeriodicalController extends Controller { $parkId = $request->input('park_id'); - // 契約状況 - $bicycleGeneral = DB::table('regular_contract') - ->where('park_id', $parkId) - ->where('user_categoryid', 1) - ->where('ptype_id', 1) // 1:自転車 - ->where('contract_cancel_flag', 0) - ->count(); - $bicycleStudent = DB::table('regular_contract') - ->where('park_id', $parkId) - ->where('user_categoryid', 2) - ->where('ptype_id', 1) - ->where('contract_cancel_flag', 0) - ->count(); - // 原付・その他も同様に集計 - - $contractSummary = [ - [ - 'type' => '自転車', - 'general_count' => $bicycleGeneral, - 'general_extra' => '', - 'student_count' => $bicycleStudent, - 'student_extra' => '', - 'use_total' => $bicycleGeneral + $bicycleStudent, - 'vacancy' => 8, // 例: 空き数 - 'total' => $bicycleGeneral + $bicycleStudent + 8, - 'last' => [ - 'reserve_date' => '2025/07/27', - 'contract_date' => '', - ], - ], - // 原付・その他も同様に - ]; - - // 空き待ち状況 - $waitingSummary = [ - [ - 'type' => '自転車', - 'general_count' => 28, - 'general_head' => '2023/03/08', - 'student_count' => 6, - 'student_head' => '2023/11/04', - 'total' => 34, - ], - // 原付・その他も同様に - ]; - - // 更新状況 - $renewalSummary = []; - for ($m = 1; $m <= 12; $m++) { - $renewalSummary[] = [ - 'month' => sprintf('%02d月', $m), - 'bicycle_general' => 0, - 'bicycle_student' => 0, - 'bicycle_total' => 0, - 'moped_general' => 0, - 'moped_student' => 0, - 'moped_total' => 0, - 'others_general' => 0, - 'others_student' => 0, - 'others_total' => 0, - ]; + if (empty($parkId)) { + return response()->json([ + 'contract_summary' => [], + 'waiting_summary' => [], + 'renewal_summary' => [], + 'debug_info' => ['message' => 'No park_id provided'] + ]); } + // デバッグ情報を収集 + $debugInfo = [ + 'park_id' => $parkId, + 'has_regular_type_id' => false, + 'contract_count' => 0, + 'waiting_count' => 0, + 'renewal_count' => 0 + ]; + + + + // 契約状況を車種別に集計 + $contractData = [ + ['psection_id' => 1, 'type' => '自転車'], + ['psection_id' => 2, 'type' => '原付'], + ['psection_id' => 0, 'type' => 'その他'] // その他は psection_id が1,2以外 + ]; + + $contractSummary = []; + $totalGeneral = 0; + $totalStudent = 0; + $totalUseTotal = 0; + $totalVacancy = 0; + $totalAll = 0; + + foreach ($contractData as $vehicleType) { + $query = DB::table('regular_contract as rc') + ->leftJoin('psection as ps', 'rc.psection_id', '=', 'ps.psection_id') + ->selectRaw('SUM(CASE WHEN rc.user_categoryid = 1 THEN 1 ELSE 0 END) AS general_count') + ->selectRaw('SUM(CASE WHEN rc.user_categoryid = 2 THEN 1 ELSE 0 END) AS student_count') + ->selectRaw('SUM(CASE WHEN rc.contract_cancel_flag = 0 THEN 1 ELSE 0 END) AS use_total') + ->selectRaw('SUM(CASE WHEN rc.contract_cancel_flag = 1 THEN 1 ELSE 0 END) AS vacancy') + ->selectRaw('COUNT(*) AS total') + ->where('rc.park_id', $parkId); + + if ($vehicleType['psection_id'] === 0) { + // その他:psection_id が 1,2 以外 + $query->whereNotIn('rc.psection_id', [1, 2]); + } else { + // 自転車または原付 + $query->where('rc.psection_id', $vehicleType['psection_id']); + } + + $result = $query->first(); + + $generalCount = (int) ($result->general_count ?? 0); + $studentCount = (int) ($result->student_count ?? 0); + $useTotal = (int) ($result->use_total ?? 0); + $vacancy = (int) ($result->vacancy ?? 0); + $total = (int) ($result->total ?? 0); + + // 最古の予約日と契約日を取得 + $minReserveQuery = DB::table('regular_contract as rc2') + ->join('reserve as r2', 'rc2.contract_id', '=', 'r2.contract_id') + ->where('rc2.park_id', $parkId) + ->where('r2.valid_flag', 1) + ->where(function ($q) { + $q->whereNull('r2.reserve_cancel_flag')->orWhere('r2.reserve_cancel_flag', 0); + }); + + if ($vehicleType['psection_id'] === 0) { + $minReserveQuery->whereNotIn('rc2.psection_id', [1, 2]); + } else { + $minReserveQuery->where('rc2.psection_id', $vehicleType['psection_id']); + } + + $minReserveDate = null; + $minContractDate = null; + + $reserveResult = $minReserveQuery->orderBy('r2.reserve_date', 'asc')->first(['r2.reserve_date']); + if ($reserveResult) { + $minReserveDate = date('Y/m/d', strtotime($reserveResult->reserve_date)); + } + + $contractResult = $minReserveQuery->orderBy('r2.reserve_end', 'asc')->first(['r2.reserve_end']); + if ($contractResult) { + $minContractDate = date('Y/m/d', strtotime($contractResult->reserve_end)); + } + + $contractSummary[] = [ + 'type' => $vehicleType['type'], + 'general_count' => $generalCount, + 'general_extra' => '', + 'student_count' => $studentCount, + 'student_extra' => '', + 'use_total' => $useTotal, + 'vacancy' => $vacancy, + 'total' => $total, + 'last' => ['reserve_date' => $minReserveDate, 'contract_date' => $minContractDate], + ]; + + $totalGeneral += $generalCount; + $totalStudent += $studentCount; + $totalUseTotal += $useTotal; + $totalVacancy += $vacancy; + $totalAll += $total; + } + + // 合計行を追加 + $contractSummary[] = [ + 'type' => '計', + 'general_count' => $totalGeneral, + 'general_extra' => '', + 'student_count' => $totalStudent, + 'student_extra' => '', + 'use_total' => $totalUseTotal, + 'vacancy' => $totalVacancy, + 'total' => $totalAll, + 'last' => ['reserve_date' => null, 'contract_date' => null], + ]; + + $debugInfo['contract_count'] = count($contractSummary); + + // 空き待ち状況を車種別に集計 + $waitingData = [ + ['psection_id' => 1, 'type' => '自転車'], + ['psection_id' => 2, 'type' => '原付'], + ['psection_id' => 0, 'type' => 'その他'] // その他は psection_id が1,2以外 + ]; + + $waitingSummary = []; + $totalGeneral = 0; + $totalStudent = 0; + $totalAll = 0; + + foreach ($waitingData as $vehicleType) { + $query = DB::table('regular_contract as rc') + ->join('reserve as r', 'rc.contract_id', '=', 'r.contract_id') + ->selectRaw('SUM(CASE WHEN rc.user_categoryid = 1 THEN 1 ELSE 0 END) AS general_count') + ->selectRaw('DATE_FORMAT(MIN(CASE WHEN rc.user_categoryid = 1 THEN r.reserve_date END), "%Y/%m/%d") AS general_first') + ->selectRaw('SUM(CASE WHEN rc.user_categoryid = 2 THEN 1 ELSE 0 END) AS student_count') + ->selectRaw('DATE_FORMAT(MIN(CASE WHEN rc.user_categoryid = 2 THEN r.reserve_date END), "%Y/%m/%d") AS student_first') + ->selectRaw('COUNT(*) AS total') + ->where('rc.park_id', $parkId) + ->where('r.valid_flag', 1) + ->where(function ($q) { + $q->whereNull('r.reserve_cancel_flag')->orWhere('r.reserve_cancel_flag', 0); + }); + + if ($vehicleType['psection_id'] === 0) { + // その他:psection_id が 1,2 以外 + $query->whereNotIn('rc.psection_id', [1, 2]); + } else { + // 自転車または原付 + $query->where('rc.psection_id', $vehicleType['psection_id']); + } + + $result = $query->first(); + + $generalCount = (int) ($result->general_count ?? 0); + $studentCount = (int) ($result->student_count ?? 0); + $typeTotal = $generalCount + $studentCount; + + $waitingSummary[] = [ + 'type' => $vehicleType['type'], + 'general_count' => $generalCount, + 'general_first' => $result->general_first ?? null, + 'student_count' => $studentCount, + 'student_first' => $result->student_first ?? null, + 'total' => $typeTotal, + ]; + + $totalGeneral += $generalCount; + $totalStudent += $studentCount; + $totalAll += $typeTotal; + } + + // 合計行を追加 + $waitingSummary[] = [ + 'type' => '計', + 'general_count' => $totalGeneral, + 'general_first' => null, + 'student_count' => $totalStudent, + 'student_first' => null, + 'total' => $totalAll, + ]; + + $debugInfo['waiting_count'] = count($waitingSummary); + + // まず期間タイプフィールドが存在するかチェック + $hasRegularTypeId = false; + try { + $columns = DB::select('DESCRIBE regular_contract'); + foreach ($columns as $column) { + if ($column->Field === 'regular_type_id') { + $hasRegularTypeId = true; + break; + } + } + } catch (\Exception $e) { + // エラーの場合はデフォルトで false + } + + $debugInfo['has_regular_type_id'] = $hasRegularTypeId; + + $renewalQuery = DB::table('regular_contract as rc') + ->join('reserve as r', 'rc.contract_id', '=', 'r.contract_id') + ->where('rc.park_id', $parkId) + ->whereNotNull('r.reserve_start') + ->where('r.valid_flag', 1) + ->selectRaw("DATE_FORMAT(r.reserve_start, '%Y-%m') AS month"); + + if ($hasRegularTypeId) { + $renewalQuery->selectRaw('COALESCE(rc.regular_type_id, 1) AS period_type'); + } else { + $renewalQuery->selectRaw('1 AS period_type'); // デフォルト値 + } + + $renewalSummary = $renewalQuery + ->selectRaw('SUM(CASE WHEN rc.psection_id = 1 AND rc.user_categoryid = 1 THEN 1 ELSE 0 END) AS bicycle_general') + ->selectRaw('SUM(CASE WHEN rc.psection_id = 1 AND rc.user_categoryid = 2 THEN 1 ELSE 0 END) AS bicycle_student') + ->selectRaw('SUM(CASE WHEN rc.psection_id = 2 AND rc.user_categoryid = 1 THEN 1 ELSE 0 END) AS moped_general') + ->selectRaw('SUM(CASE WHEN rc.psection_id = 2 AND rc.user_categoryid = 2 THEN 1 ELSE 0 END) AS moped_student') + ->selectRaw('SUM(CASE WHEN rc.psection_id NOT IN (1,2) AND rc.user_categoryid = 1 THEN 1 ELSE 0 END) AS other_general') + ->selectRaw('SUM(CASE WHEN rc.psection_id NOT IN (1,2) AND rc.user_categoryid = 2 THEN 1 ELSE 0 END) AS other_student') + ->groupBy(['month', 'period_type']) + ->orderBy('month') + ->orderBy('period_type') + ->limit(50) + ->get(); + + // 月別期間別データを構造化 + $structuredData = []; + $periodLabels = [ + 1 => '1ヶ月', + 2 => '2ヶ月', + 3 => '3ヶ月', + 6 => '6ヶ月', + 12 => '12ヶ月' + ]; + + // regular_type_id がない場合のデフォルト処理 + if (!$hasRegularTypeId) { + // フィールドがない場合は、月ごとに「計」行のみ表示 + $monthlyTotals = []; + foreach ($renewalSummary as $row) { + $monthKey = $row->month; + if (!isset($monthlyTotals[$monthKey])) { + $monthlyTotals[$monthKey] = [ + 'bicycle_general' => 0, + 'bicycle_student' => 0, + 'moped_general' => 0, + 'moped_student' => 0, + 'other_general' => 0, + 'other_student' => 0, + ]; + } + + $monthlyTotals[$monthKey]['bicycle_general'] += (int) $row->bicycle_general; + $monthlyTotals[$monthKey]['bicycle_student'] += (int) $row->bicycle_student; + $monthlyTotals[$monthKey]['moped_general'] += (int) $row->moped_general; + $monthlyTotals[$monthKey]['moped_student'] += (int) $row->moped_student; + $monthlyTotals[$monthKey]['other_general'] += (int) $row->other_general; + $monthlyTotals[$monthKey]['other_student'] += (int) $row->other_student; + } + + foreach ($monthlyTotals as $monthKey => $totals) { + $structuredData[$monthKey] = [ + 'month' => $monthKey, + 'rows' => [[ + 'label' => '計', + 'bicycle_general' => $totals['bicycle_general'], + 'bicycle_student' => $totals['bicycle_student'], + 'bicycle_total' => $totals['bicycle_general'] + $totals['bicycle_student'], + 'moped_general' => $totals['moped_general'], + 'moped_student' => $totals['moped_student'], + 'moped_total' => $totals['moped_general'] + $totals['moped_student'], + 'other_general' => $totals['other_general'], + 'other_student' => $totals['other_student'], + 'other_total' => $totals['other_general'] + $totals['other_student'], + ]] + ]; + } + } else { + // regular_type_id がある場合の通常処理 + foreach ($renewalSummary as $row) { + $monthKey = $row->month; + $periodType = (int)$row->period_type; + $periodLabel = $periodLabels[$periodType] ?? "{$periodType}ヶ月"; + + if (!isset($structuredData[$monthKey])) { + $structuredData[$monthKey] = [ + 'month' => $monthKey, + 'rows' => [], + 'totals' => [ + 'bicycle_general' => 0, + 'bicycle_student' => 0, + 'moped_general' => 0, + 'moped_student' => 0, + 'other_general' => 0, + 'other_student' => 0, + ] + ]; + } + + $bicycle_total = (int) $row->bicycle_general + (int) $row->bicycle_student; + $moped_total = (int) $row->moped_general + (int) $row->moped_student; + $other_total = (int) $row->other_general + (int) $row->other_student; + + // 期間別データを追加 + $structuredData[$monthKey]['rows'][] = [ + 'label' => $periodLabel, + 'bicycle_general' => (int) $row->bicycle_general, + 'bicycle_student' => (int) $row->bicycle_student, + 'bicycle_total' => $bicycle_total, + 'moped_general' => (int) $row->moped_general, + 'moped_student' => (int) $row->moped_student, + 'moped_total' => $moped_total, + 'other_general' => (int) $row->other_general, + 'other_student' => (int) $row->other_student, + 'other_total' => $other_total, + ]; + + // 月別合計を計算 + $structuredData[$monthKey]['totals']['bicycle_general'] += (int) $row->bicycle_general; + $structuredData[$monthKey]['totals']['bicycle_student'] += (int) $row->bicycle_student; + $structuredData[$monthKey]['totals']['moped_general'] += (int) $row->moped_general; + $structuredData[$monthKey]['totals']['moped_student'] += (int) $row->moped_student; + $structuredData[$monthKey]['totals']['other_general'] += (int) $row->other_general; + $structuredData[$monthKey]['totals']['other_student'] += (int) $row->other_student; + } + + // 各月に計行を追加 + foreach ($structuredData as &$monthData) { + $totals = $monthData['totals']; + $monthData['rows'][] = [ + 'label' => '計', + 'bicycle_general' => $totals['bicycle_general'], + 'bicycle_student' => $totals['bicycle_student'], + 'bicycle_total' => $totals['bicycle_general'] + $totals['bicycle_student'], + 'moped_general' => $totals['moped_general'], + 'moped_student' => $totals['moped_student'], + 'moped_total' => $totals['moped_general'] + $totals['moped_student'], + 'other_general' => $totals['other_general'], + 'other_student' => $totals['other_student'], + 'other_total' => $totals['other_general'] + $totals['other_student'], + ]; + } + } + + $renewalSummary = array_values($structuredData); + + $debugInfo['renewal_count'] = count($renewalSummary); + return response()->json([ 'contract_summary' => $contractSummary, - 'waiting_summary' => $waitingSummary, - 'renewal_summary' => $renewalSummary, + 'waiting_summary' => $waitingSummary, + 'renewal_summary' => $renewalSummary, + 'debug_info' => $debugInfo ]); } } +?> \ No newline at end of file diff --git a/resources/views/admin/periodical/list.blade.php b/resources/views/admin/periodical/list.blade.php index a024bb7..a914d34 100644 --- a/resources/views/admin/periodical/list.blade.php +++ b/resources/views/admin/periodical/list.blade.php @@ -4,223 +4,243 @@ @section('content')
-
-
-
-

定期利用・契約状況

-
-
- -
-
+
+
+

定期利用・契約状況

+
+ +
+
-
- - {{-- 検索条件 --}} -
-
-
- - -
- 以下に記載以外の期間情報を参照したい場合は、マスタ管理>定期期間マスタ のCSV出力を利用してください。 -
-
- - {{-- 契約状況 --}} -
-
- 契約状況 -
-
-
- - - - - - - - - - - - - - - - - - - - - -
契約状況一般学生利用計空き合計直近契約
件数件数予約日契約日
-
-
-
- - {{-- 空き待ち状況 --}} -
-
- 空き待ち状況 -
-
-
- - - - - - - - - - - - - - - - -
空き待ち状況一般学生合計
件数先頭日件数先頭日
-
-
-
- - {{-- 更新状況 --}} -
-
- 更新状況 -
-
-
- - - - - - - - - - - - - - - - - - - - - -
自転車原付その他
一般学生一般学生一般学生
-
-
-
- +
+
+
+ + +
+ + 以下に記載以外の期間情報を参照したい場合は、マスタ管理>定期期間マスタのCSV出力を利用してください。 +
+ + +
+@endsection @push('scripts') @endpush -@endsection