so-manager-dev.com/app/Http/Controllers/ParkDetailController.php

262 lines
9.0 KiB
PHP
Raw 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\Http\Controllers;
use App\Http\Traits\AuthenticatesUser;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;
class ParkDetailController extends Controller
{
use AuthenticatesUser;
/**
* 駐輪場詳細情報を取得Ajax用
*
* @param string $management_code
* @param int $park_id
* @return \Illuminate\Http\JsonResponse
*/
public function show($management_code, $park_id)
{
if ($redirect = $this->handleSessionExpired('駐輪場詳細', false)) {
return $redirect;
}
$userId = session('user_id');
$management = session('management');
if (!$management) {
\Log::error("[ERROR] " . now()->format('Y-m-d H:i:s') . " 運営元情報取得失敗 user_id=" . $userId);
return response()->json(['error' => 'Management not found'], 404);
}
// マルチテナント対応:運営元に紐づく駐輪場のみ取得
$park = $this->getParkInfo($park_id, $management->management_id);
if (!$park) {
\Log::error("[ERROR] " . now()->format('Y-m-d H:i:s') . " 駐輪場情報取得失敗 park_id=" . $park_id . ", management_id=" . $management->management_id . ", user_id=" . $userId);
return response()->json(['error' => 'Park not found'], 404);
}
$park = DB::table('park')->where('park_id', $park_id)->first();
// ゾーン情報取得
$zones = $this->getZones($park_id);
// 予約情報取得
$reserves = $this->getReserves($park_id);
// 車種別の基準台数集計
$zoneStandardSum = $this->calculateZoneStandardSum($zones);
// 車種別の空き台数計算
$vacancyData = $this->calculateVacancy($zones, $reserves);
// 駐輪場ごとの更新可能期間取得
$parkGracePeriod = $this->getParkGracePeriod($park_id);
\Log::info("[INFO] " . now()->format('Y-m-d H:i:s') . " 駐輪場詳細取得成功 park_id=" . $park_id . ", management_id=" . $management->management_id . ", user_id=" . $userId);
try {
$html = view('regular_contract.park_detail', compact(
'park',
'zones',
'reserves',
'zoneStandardSum',
'vacancyData',
'parkGracePeriod'
))->render();
\Log::info("[INFO] " . now()->format('Y-m-d H:i:s') . " ビュー生成成功 park_id=" . $park_id . ", HTML長=" . strlen($html));
return response()->json(['html' => $html]);
} catch (\Exception $e) {
\Log::error("[ERROR] " . now()->format('Y-m-d H:i:s') . " ビュー生成失敗 park_id=" . $park_id . ", error=" . $e->getMessage());
return response()->json(['error' => 'View rendering failed'], 500);
}
}
/**
* 駐輪場情報取得(マルチテナントフィルタ適用)
*
* なぜ: 運営元に紐づく駐輪場のみ取得するため
*
* @param int $parkId
* @param int $managementId
* @return object|null
*/
private function getParkInfo(int $parkId, int $managementId)
{
try {
return DB::table('park')
->where('park_id', $parkId)
->where('management_id', $managementId)
->first();
} catch (\Exception $e) {
\Log::error("[ERROR] " . now()->format('Y-m-d H:i:s') . " 駐輪場情報取得エラー park_id=" . $parkId . ", error=" . $e->getMessage());
return null;
}
}
/**
* zone情報取得
*
* @param int $parkId
* @return \Illuminate\Support\Collection
*/
private function getZones(int $parkId)
{
try {
return DB::table('zone')
->leftJoin('psection', 'zone.psection_id', '=', 'psection.psection_id')
->leftJoin('ptype', 'zone.ptype_id', '=', 'ptype.ptype_id')
->select(
'zone.*',
'psection.psection_subject',
'ptype.ptype_subject'
)
->where('zone.park_id', $parkId)
->get();
} catch (\Exception $e) {
\Log::error("[ERROR] " . now()->format('Y-m-d H:i:s') . " zone情報取得失敗 park_id=" . $parkId . ", error=" . $e->getMessage());
return collect();
}
}
/**
* reserve情報取得
*
* @param int $parkId
* @return \Illuminate\Support\Collection
*/
private function getReserves(int $parkId)
{
try {
return DB::table('reserve')
->join('zone', function ($join) {
$join->on('reserve.psection_id', '=', 'zone.psection_id')
->on('reserve.ptype_id', '=', 'zone.ptype_id');
})
->join('ptype', 'zone.ptype_id', '=', 'ptype.ptype_id')
->where('reserve.park_id', $parkId)
->where('reserve.valid_flag', 1)
->select('reserve.*', 'ptype.ptype_subject')
->get();
} catch (\Exception $e) {
\Log::error("[ERROR] " . now()->format('Y-m-d H:i:s') . " reserve情報取得失敗 park_id=" . $parkId . ", error=" . $e->getMessage());
return collect();
}
}
/**
* 車種別の基準台数集計
*
* なぜ: 駐輪場の車種別定員を把握するため
*
* @param \Illuminate\Support\Collection $zones
* @return array
*/
private function calculateZoneStandardSum($zones)
{
$zoneStandardSum = [];
foreach ($zones as $zone) {
$key = $zone->psection_subject; // 「自転車」「原付」など
if (!isset($zoneStandardSum[$key])) {
$zoneStandardSum[$key] = 0;
}
$zoneStandardSum[$key] += $zone->zone_standard;
}
return $zoneStandardSum;
}
/**
* 車種別の空き台数計算
*
* なぜ: reserve予約を考慮した実際の空き台数を算出するため
*
* @param \Illuminate\Support\Collection $zones
* @param \Illuminate\Support\Collection $reserves
* @return array
*/
private function calculateVacancy($zones, $reserves)
{
$vacancyData = [];
// zone_tolerance - zone_number を集計
foreach ($zones as $zone) {
$key = $zone->psection_id . '_' . $zone->ptype_subject;
if (!isset($vacancyData[$key])) {
$vacancyData[$key] = 0;
}
$vacancyData[$key] += ($zone->zone_tolerance - $zone->zone_number);
}
// reserve件数分を減算
foreach ($reserves as $reserve) {
$key = $reserve->psection_id . '_' . $reserve->ptype_subject;
if (isset($vacancyData[$key])) {
$vacancyData[$key] -= 1;
}
}
return $vacancyData;
}
/**
* 駐輪場の更新可能期間取得
*
* なぜ: 更新可能期間がcityテーブルからparkテーブルに変更されたため
*
* @param int $parkId
* @return object|null
*/
private function getParkGracePeriod(int $parkId)
{
try {
return DB::table('park')
->select(
'park_id',
'update_grace_period_start_date',
'update_grace_period_start_time',
'update_grace_period_end_date',
'update_grace_period_end_time'
)
->where('park_id', $parkId)
->first();
} catch (\Exception $e) {
\Log::error("[ERROR] " . now()->format('Y-m-d H:i:s') . " 駐輪場更新可能期間取得失敗 park_id=" . $parkId . ", error=" . $e->getMessage());
return null;
}
}
public function showWait($reserve_id)
{
$reserve = DB::table('reserve')->where('reserve_id', $reserve_id)->first();
$park = DB::table('park')->where('park_id', $reserve->park_id)->first();
$zones = DB::table('zone')
->leftJoin('psection', 'zone.psection_id', '=', 'psection.psection_id')
->leftJoin('ptype', 'zone.ptype_id', '=', 'ptype.ptype_id')
->select('zone.*', 'psection.psection_subject', 'ptype.ptype_subject')
->where('zone.park_id', $park->park_id)
->get();
$zoneStandardSum = [];
foreach ($zones as $zone) {
$key = $zone->psection_subject; // 「自転車」「原付」など
if (!isset($zoneStandardSum[$key])) {
$zoneStandardSum[$key] = 0;
}
$zoneStandardSum[$key] += $zone->zone_standard;
}
// 必要なら他テーブルJOINや追加情報も取得
return response()->json([
'html' => view('park_waitlist.park_detail', compact('park', 'zones', 'reserve', 'zoneStandardSum'))->render()
]);
}
}