Compare commits
2 Commits
c728744d9e
...
637312661e
| Author | SHA1 | Date | |
|---|---|---|---|
| 637312661e | |||
| c1a9fc80c8 |
@ -2,35 +2,165 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Traits\AuthenticatesUser;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
class ParkDetailController extends Controller
|
class ParkDetailController extends Controller
|
||||||
{
|
{
|
||||||
public function show($park_id)
|
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();
|
$park = DB::table('park')->where('park_id', $park_id)->first();
|
||||||
|
|
||||||
$zones = DB::table('zone')
|
// ゾーン情報取得
|
||||||
->leftJoin('psection', 'zone.psection_id', '=', 'psection.psection_id')
|
$zones = $this->getZones($park_id);
|
||||||
->leftJoin('ptype', 'zone.ptype_id', '=', 'ptype.ptype_id')
|
|
||||||
->select('zone.*', 'psection.psection_subject', 'ptype.ptype_subject')
|
|
||||||
->where('zone.park_id', $park_id)
|
|
||||||
->get();
|
|
||||||
|
|
||||||
$reserves = DB::table('reserve')
|
// 予約情報取得
|
||||||
->join('zone', function ($join) {
|
$reserves = $this->getReserves($park_id);
|
||||||
$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', $park_id)
|
|
||||||
->where('reserve.valid_flag', 1)
|
|
||||||
->select('reserve.*', 'ptype.ptype_subject')
|
|
||||||
->get();
|
|
||||||
|
|
||||||
|
// 車種別の基準台数集計
|
||||||
|
$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 = [];
|
$zoneStandardSum = [];
|
||||||
|
|
||||||
foreach ($zones as $zone) {
|
foreach ($zones as $zone) {
|
||||||
$key = $zone->psection_subject; // 「自転車」「原付」など
|
$key = $zone->psection_subject; // 「自転車」「原付」など
|
||||||
if (!isset($zoneStandardSum[$key])) {
|
if (!isset($zoneStandardSum[$key])) {
|
||||||
@ -39,14 +169,28 @@ class ParkDetailController extends Controller
|
|||||||
$zoneStandardSum[$key] += $zone->zone_standard;
|
$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 = [];
|
$vacancyData = [];
|
||||||
|
|
||||||
|
// zone_tolerance - zone_number を集計
|
||||||
foreach ($zones as $zone) {
|
foreach ($zones as $zone) {
|
||||||
$key = $zone->psection_id . '_' . $zone->ptype_subject;
|
$key = $zone->psection_id . '_' . $zone->ptype_subject;
|
||||||
if (!isset($vacancyData[$key])) {
|
if (!isset($vacancyData[$key])) {
|
||||||
$vacancyData[$key] = 0;
|
$vacancyData[$key] = 0;
|
||||||
}
|
}
|
||||||
// zone_tolerance - zone_number を合計
|
|
||||||
$vacancyData[$key] += ($zone->zone_tolerance - $zone->zone_number);
|
$vacancyData[$key] += ($zone->zone_tolerance - $zone->zone_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,23 +198,38 @@ class ParkDetailController extends Controller
|
|||||||
foreach ($reserves as $reserve) {
|
foreach ($reserves as $reserve) {
|
||||||
$key = $reserve->psection_id . '_' . $reserve->ptype_subject;
|
$key = $reserve->psection_id . '_' . $reserve->ptype_subject;
|
||||||
if (isset($vacancyData[$key])) {
|
if (isset($vacancyData[$key])) {
|
||||||
$vacancyData[$key] -= 1; // 1件分減算
|
$vacancyData[$key] -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新期間取得
|
return $vacancyData;
|
||||||
$city_grace_periods = DB::table('city')
|
}
|
||||||
->select('city_id', 'update_grace_period_start_date', 'update_grace_period_start_time', 'update_grace_period_end_date', 'update_grace_period_end_time')
|
|
||||||
->whereIn('city_id', function ($query) {
|
|
||||||
$query->select('city_id')->from('park');
|
|
||||||
})
|
|
||||||
->get()
|
|
||||||
->keyBy('city_id');
|
|
||||||
|
|
||||||
// 必要なら他テーブルJOINや追加情報も取得
|
/**
|
||||||
return response()->json([
|
* 駐輪場の更新可能期間取得
|
||||||
'html' => view('regular_contract.park_detail', compact('park', 'zones', 'reserves', 'zoneStandardSum', 'vacancyData', 'city_grace_periods'))->render()
|
*
|
||||||
]);
|
* なぜ: 更新可能期間が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)
|
public function showWait($reserve_id)
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Traits\AuthenticatesUser;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Session;
|
use Illuminate\Support\Facades\Session;
|
||||||
@ -16,150 +17,440 @@ use Carbon\Carbon;
|
|||||||
|
|
||||||
class RegularContractCreateController extends Controller
|
class RegularContractCreateController extends Controller
|
||||||
{
|
{
|
||||||
// 新規作成画面表示
|
use AuthenticatesUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 駐輪場選択画面を表示
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @return \Illuminate\View\View|\Illuminate\Http\RedirectResponse
|
||||||
|
*/
|
||||||
public function show(Request $request)
|
public function show(Request $request)
|
||||||
{
|
{
|
||||||
$user_id = session('user_id');
|
if ($redirect = $this->handleSessionExpired('駐輪場選択')) {
|
||||||
if (!$user_id) {
|
return $redirect;
|
||||||
return redirect('/login');
|
|
||||||
}
|
}
|
||||||
$user = DB::table('user')->where('user_id', $user_id)->first();
|
|
||||||
|
|
||||||
// 市町村名(park→city JOINで重複排除)
|
$userId = session('user_id');
|
||||||
$cities = DB::table('park')
|
$user = DB::table('user')->where('user_id', $userId)->first();
|
||||||
->join('city', 'park.city_id', '=', 'city.city_id')
|
|
||||||
->select('city.city_id', 'city.city_name')
|
|
||||||
->distinct()
|
|
||||||
->get();
|
|
||||||
|
|
||||||
// city_idごとの更新可能期間情報を取得
|
// マルチテナント対応のため、運営元情報をセッションから取得
|
||||||
$city_grace_periods = DB::table('city')
|
$management = session('management');
|
||||||
->select('city_id', 'update_grace_period_start_date', 'update_grace_period_start_time', 'update_grace_period_end_date', 'update_grace_period_end_time')
|
if (!$management) {
|
||||||
->get()
|
\Log::error("[ERROR] " . now()->format('Y-m-d H:i:s') . " 運営元情報が見つからない user_id=" . $userId);
|
||||||
->keyBy('city_id');
|
abort(404);
|
||||||
|
}
|
||||||
|
|
||||||
// 駅名(stationテーブルのstation_neighbor_station全件)
|
// 検索条件・ページング取得
|
||||||
$stations = DB::table('station')
|
$cityId = $request->input('city_id');
|
||||||
->select('station_neighbor_station')
|
$stationName = $request->input('station_neighbor_station');
|
||||||
->distinct()
|
$parkId = $request->input('park_id');
|
||||||
->get();
|
$page = (int)$request->input('page', 1);
|
||||||
|
|
||||||
// 駐輪場名(parkテーブルのpark_name全件)
|
|
||||||
$parks = DB::table('park')
|
|
||||||
->select('park_id', 'park_name')
|
|
||||||
->distinct()
|
|
||||||
->get();
|
|
||||||
|
|
||||||
// テーブル表示用データ(park/city/station JOIN, park_id昇順, 10件ずつページング)
|
|
||||||
$page = request()->input('page', 1);
|
|
||||||
$perPage = 10;
|
$perPage = 10;
|
||||||
$city_id = request()->input('city_id');
|
|
||||||
$station_name = request()->input('station_neighbor_station');
|
|
||||||
$park_id = request()->input('park_id');
|
|
||||||
|
|
||||||
$query = DB::table('park')
|
// ルート名で画面種別判定(新規定期契約 or 駐輪場検索)
|
||||||
->join('city', 'park.city_id', '=', 'city.city_id')
|
|
||||||
->leftJoin('station', 'park.park_id', '=', 'station.park_id')
|
|
||||||
->select(
|
|
||||||
'park.park_id',
|
|
||||||
'park.park_name',
|
|
||||||
'park.park_ruby',
|
|
||||||
'city.city_name',
|
|
||||||
'city.city_id',
|
|
||||||
'station.station_neighbor_station',
|
|
||||||
'station.station_name_ruby'
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($city_id) {
|
|
||||||
$query->where('city.city_id', $city_id);
|
|
||||||
}
|
|
||||||
if ($station_name) {
|
|
||||||
$query->where('station.station_neighbor_station', $station_name);
|
|
||||||
}
|
|
||||||
if ($park_id) {
|
|
||||||
$query->where('park.park_id', $park_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 並び替えパラメータ取得
|
|
||||||
$sort = request()->input('sort', 'park_id');
|
|
||||||
$order = request()->input('order', 'asc');
|
|
||||||
$sortable = [
|
|
||||||
'park_ruby' => 'park.park_ruby',
|
|
||||||
'city_id' => 'city.city_id',
|
|
||||||
'station_name_ruby' => 'station.station_name_ruby',
|
|
||||||
'park_id' => 'park.park_id',
|
|
||||||
];
|
|
||||||
$query->orderBy('park.park_id', 'asc');
|
|
||||||
|
|
||||||
$total = $query->count();
|
|
||||||
$parks_table = $query->get();
|
|
||||||
|
|
||||||
if ($sort === 'park_ruby' || $sort === 'station_name_ruby') {
|
|
||||||
$collator = new \Collator('ja');
|
|
||||||
$parks_table = $parks_table->sort(function ($a, $b) use ($order, $sort, $collator) {
|
|
||||||
$a_val = $a->$sort ?? '';
|
|
||||||
$b_val = $b->$sort ?? '';
|
|
||||||
return $order === 'asc'
|
|
||||||
? $collator->compare($a_val, $b_val)
|
|
||||||
: $collator->compare($b_val, $a_val);
|
|
||||||
})->values();
|
|
||||||
} else {
|
|
||||||
// park_id, city_idなどはSQLのorderByで十分なので、ここでPHPソートは不要
|
|
||||||
if (isset($sortable[$sort])) {
|
|
||||||
$parks_table = $parks_table->sortBy($sort, SORT_REGULAR, $order === 'desc')->values();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$page = request()->input('page', 1);
|
|
||||||
$perPage = 10;
|
|
||||||
$parks_table = $parks_table->slice(($page - 1) * $perPage, $perPage)->values();
|
|
||||||
|
|
||||||
// zoneテーブルデータを取得(psectionテーブルとJOINしてpsection_subjectも取得)
|
|
||||||
$zones = DB::table('zone')
|
|
||||||
->leftJoin('psection', 'zone.psection_id', '=', 'psection.psection_id')
|
|
||||||
->select('zone.zone_id', 'zone.park_id', 'zone.ptype_id', 'zone.psection_id', 'zone.zone_number', 'zone.zone_tolerance', 'psection.psection_subject')
|
|
||||||
->get()
|
|
||||||
->groupBy('park_id');
|
|
||||||
|
|
||||||
// 空き予約マスタデータを取得
|
|
||||||
$reserve = DB::table('reserve')
|
|
||||||
->select('reserve_id', 'park_id', 'ptype_id', 'psection_id')
|
|
||||||
->where('valid_flag', 1)
|
|
||||||
->get()
|
|
||||||
->groupBy('park_id');
|
|
||||||
|
|
||||||
// ルート名で画面表示を切り替え(新規定期契約 or 駐輪場検索)
|
|
||||||
$isRegularContract = $request->route()->getName() === 'regular_contract.create';
|
$isRegularContract = $request->route()->getName() === 'regular_contract.create';
|
||||||
|
$activeMenu = $isRegularContract ? 'SWC-8-1' : 'SWC-10-1';
|
||||||
|
|
||||||
// ヘッダーの選択状態を分岐
|
// マスタデータ取得(運営元フィルタ適用)
|
||||||
$active_menu = $isRegularContract ? 'SWC-8-1' : 'SWC-10-1';
|
$cities = $this->getCitiesList($management->management_id);
|
||||||
|
$stations = $this->getStationsList($management->management_id);
|
||||||
|
$parks = $this->getParksList($management->management_id);
|
||||||
|
|
||||||
if ($isRegularContract) {
|
// 運営元が取り扱う車種一覧を取得
|
||||||
\Log::info('新規定期契約-駐輪場選択画面にアクセス', [
|
$availableVehicles = $this->getAvailableVehicles($management->management_id);
|
||||||
'user_id' => $user_id,
|
|
||||||
]);
|
// 駐輪場テーブルデータ取得(検索・ページング、運営元フィルタ適用)
|
||||||
} else {
|
$parksTableData = $this->getParksTableData($management->management_id, $cityId, $stationName, $parkId, $page, $perPage);
|
||||||
\Log::info('駐輪場検索-駐輪場選択画面にアクセス', [
|
|
||||||
'user_id' => $user_id,
|
// zone・reserve マスタ取得(運営元フィルタ適用)
|
||||||
]);
|
$zones = $this->getZonesByParkId($management->management_id);
|
||||||
}
|
$reserve = $this->getReserveByParkId($management->management_id);
|
||||||
|
|
||||||
|
// 駐輪場ごとの更新可能期間取得(運営元フィルタ適用)
|
||||||
|
$parkGracePeriods = $this->getParkGracePeriods($management->management_id);
|
||||||
|
|
||||||
|
// 駐輪場ごと・車種ごとの状態を事前計算
|
||||||
|
$parksTableData['data'] = $this->calculateVehicleStatus(
|
||||||
|
$parksTableData['data'],
|
||||||
|
$zones,
|
||||||
|
$reserve,
|
||||||
|
$parkGracePeriods,
|
||||||
|
$availableVehicles
|
||||||
|
);
|
||||||
|
|
||||||
|
// アクセスログ記録
|
||||||
|
$screenName = $isRegularContract ? '新規定期契約登録' : '駐輪場検索';
|
||||||
|
\Log::info("[INFO] " . now()->format('Y-m-d H:i:s') . " {$screenName}画面アクセス user_id=" . $userId . ", management_id=" . $management->management_id . ", city_id=" . ($cityId ?? 'null') . ", park_id=" . ($parkId ?? 'null'));
|
||||||
|
|
||||||
return view('regular_contract.create', [
|
return view('regular_contract.create', [
|
||||||
'active_menu' => $active_menu, // この画面のID
|
'active_menu' => $activeMenu,
|
||||||
'user_name' => $user ? $user->user_name : '', // ユーザー名(ヘッダー用)
|
'user_name' => $user->user_name ?? '',
|
||||||
'cities' => $cities,
|
'cities' => $cities,
|
||||||
'stations' => $stations,
|
'stations' => $stations,
|
||||||
'parks' => $parks,
|
'parks' => $parks,
|
||||||
'parks_table' => $parks_table,
|
'parks_table' => $parksTableData['data'],
|
||||||
'parks_table_total' => $total,
|
'parks_table_total' => $parksTableData['total'],
|
||||||
'parks_table_page' => $page,
|
'parks_table_page' => $page,
|
||||||
'parks_table_perPage' => $perPage,
|
'parks_table_perPage' => $perPage,
|
||||||
'zones' => $zones,
|
'available_vehicles' => $availableVehicles,
|
||||||
'city_grace_periods' => $city_grace_periods,
|
|
||||||
'reserve' => $reserve,
|
'reserve' => $reserve,
|
||||||
'isRegularContract' => $isRegularContract
|
'isRegularContract' => $isRegularContract,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 市町村一覧取得(運営元フィルタ適用)
|
||||||
|
* マルチテナント対応のため、運営元に紐づく駐輪場の市町村のみ表示
|
||||||
|
*
|
||||||
|
* @param int $managementId
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
private function getCitiesList(int $managementId)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return DB::table('park')
|
||||||
|
->join('city', 'park.city_id', '=', 'city.city_id')
|
||||||
|
->where('park.management_id', $managementId)
|
||||||
|
->select('city.city_id', 'city.city_name')
|
||||||
|
->distinct()
|
||||||
|
->get();
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
\Log::error("[ERROR] " . now()->format('Y-m-d H:i:s') . " 市町村一覧取得失敗 management_id=" . $managementId . ", error=" . $e->getMessage());
|
||||||
|
return collect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 駅名一覧取得(運営元フィルタ適用)
|
||||||
|
*
|
||||||
|
* なぜ: マルチテナント対応のため、運営元に紐づく駐輪場の駅のみ表示
|
||||||
|
*
|
||||||
|
* @param int $managementId
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
private function getStationsList(int $managementId)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return DB::table('station')
|
||||||
|
->join('park', 'station.park_id', '=', 'park.park_id')
|
||||||
|
->where('park.management_id', $managementId)
|
||||||
|
->select('station.station_neighbor_station')
|
||||||
|
->distinct()
|
||||||
|
->get();
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
\Log::error("[ERROR] " . now()->format('Y-m-d H:i:s') . " 駅名一覧取得失敗 management_id=" . $managementId . ", error=" . $e->getMessage());
|
||||||
|
return collect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 駐輪場名一覧取得(運営元フィルタ適用)
|
||||||
|
*
|
||||||
|
* なぜ: マルチテナント対応のため、運営元に紐づく駐輪場のみ表示
|
||||||
|
*
|
||||||
|
* @param int $managementId
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
private function getParksList(int $managementId)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return DB::table('park')
|
||||||
|
->where('management_id', $managementId)
|
||||||
|
->select('park_id', 'park_name')
|
||||||
|
->distinct()
|
||||||
|
->get();
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
\Log::error("[ERROR] " . now()->format('Y-m-d H:i:s') . " 駐輪場名一覧取得失敗 management_id=" . $managementId . ", error=" . $e->getMessage());
|
||||||
|
return collect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 駐輪場テーブルデータ取得(検索・ページング適用、運営元フィルタ適用)
|
||||||
|
*
|
||||||
|
* なぜ: マルチテナント対応のため、運営元に紐づく駐輪場のみ表示
|
||||||
|
*
|
||||||
|
* @param int $managementId
|
||||||
|
* @param int|null $cityId
|
||||||
|
* @param string|null $stationName
|
||||||
|
* @param int|null $parkId
|
||||||
|
* @param int $page
|
||||||
|
* @param int $perPage
|
||||||
|
* @return array ['data' => Collection, 'total' => int]
|
||||||
|
*/
|
||||||
|
private function getParksTableData(int $managementId, $cityId, $stationName, $parkId, int $page, int $perPage)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$query = DB::table('park')
|
||||||
|
->join('city', 'park.city_id', '=', 'city.city_id')
|
||||||
|
->leftJoin('station', 'park.park_id', '=', 'station.park_id')
|
||||||
|
->where('park.management_id', $managementId)
|
||||||
|
->select(
|
||||||
|
'park.park_id',
|
||||||
|
'park.park_name',
|
||||||
|
'park.park_ruby',
|
||||||
|
'city.city_name',
|
||||||
|
'city.city_id',
|
||||||
|
'station.station_neighbor_station',
|
||||||
|
'station.station_name_ruby'
|
||||||
|
);
|
||||||
|
|
||||||
|
// 検索条件適用
|
||||||
|
if ($cityId) {
|
||||||
|
$query->where('city.city_id', $cityId);
|
||||||
|
}
|
||||||
|
if ($stationName) {
|
||||||
|
$query->where('station.station_neighbor_station', $stationName);
|
||||||
|
}
|
||||||
|
if ($parkId) {
|
||||||
|
$query->where('park.park_id', $parkId);
|
||||||
|
}
|
||||||
|
|
||||||
|
$query->orderBy('park.park_id', 'asc');
|
||||||
|
$total = $query->count();
|
||||||
|
|
||||||
|
// ページング適用
|
||||||
|
$data = $query
|
||||||
|
->skip(($page - 1) * $perPage)
|
||||||
|
->take($perPage)
|
||||||
|
->get();
|
||||||
|
|
||||||
|
\Log::info("[INFO] " . now()->format('Y-m-d H:i:s') . " 駐輪場データ取得成功 management_id=" . $managementId . ", 件数=" . $total . ", page=" . $page);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'data' => $data,
|
||||||
|
'total' => $total,
|
||||||
|
];
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
\Log::error("[ERROR] " . now()->format('Y-m-d H:i:s') . " 駐輪場テーブルデータ取得失敗 management_id=" . $managementId . ", error=" . $e->getMessage());
|
||||||
|
return [
|
||||||
|
'data' => collect(),
|
||||||
|
'total' => 0,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* zone データを park_id でグループ化して取得(運営元フィルタ適用)
|
||||||
|
*
|
||||||
|
* なぜ: マルチテナント対応のため、運営元に紐づく駐輪場のzoneのみ取得
|
||||||
|
*
|
||||||
|
* @param int $managementId
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
private function getZonesByParkId(int $managementId)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return DB::table('zone')
|
||||||
|
->join('park', 'zone.park_id', '=', 'park.park_id')
|
||||||
|
->leftJoin('psection', 'zone.psection_id', '=', 'psection.psection_id')
|
||||||
|
->where('park.management_id', $managementId)
|
||||||
|
->select(
|
||||||
|
'zone.zone_id',
|
||||||
|
'zone.park_id',
|
||||||
|
'zone.ptype_id',
|
||||||
|
'zone.psection_id',
|
||||||
|
'zone.zone_number',
|
||||||
|
'zone.zone_tolerance',
|
||||||
|
'psection.psection_subject'
|
||||||
|
)
|
||||||
|
->get()
|
||||||
|
->groupBy('park_id');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
\Log::error("[ERROR] " . now()->format('Y-m-d H:i:s') . " zone データ取得失敗 management_id=" . $managementId . ", error=" . $e->getMessage());
|
||||||
|
return collect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reserve データを park_id でグループ化して取得(運営元フィルタ適用)
|
||||||
|
*
|
||||||
|
* なぜ: マルチテナント対応のため、運営元に紐づく駐輪場のreserveのみ取得
|
||||||
|
*
|
||||||
|
* @param int $managementId
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
private function getReserveByParkId(int $managementId)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return DB::table('reserve')
|
||||||
|
->join('park', 'reserve.park_id', '=', 'park.park_id')
|
||||||
|
->where('park.management_id', $managementId)
|
||||||
|
->where('reserve.valid_flag', 1)
|
||||||
|
->select('reserve.reserve_id', 'reserve.park_id', 'reserve.ptype_id', 'reserve.psection_id')
|
||||||
|
->get()
|
||||||
|
->groupBy('park_id');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
\Log::error("[ERROR] " . now()->format('Y-m-d H:i:s') . " reserve データ取得失敗 management_id=" . $managementId . ", error=" . $e->getMessage());
|
||||||
|
return collect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 駐輪場ごとの更新可能期間を取得(運営元フィルタ適用)
|
||||||
|
*
|
||||||
|
* なぜ: 更新可能期間がcityテーブルからparkテーブルに変更されたため
|
||||||
|
*
|
||||||
|
* @param int $managementId
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
private function getParkGracePeriods(int $managementId)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return DB::table('park')
|
||||||
|
->where('management_id', $managementId)
|
||||||
|
->select(
|
||||||
|
'park_id',
|
||||||
|
'update_grace_period_start_date',
|
||||||
|
'update_grace_period_start_time',
|
||||||
|
'update_grace_period_end_date',
|
||||||
|
'update_grace_period_end_time'
|
||||||
|
)
|
||||||
|
->get()
|
||||||
|
->keyBy('park_id');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
\Log::error("[ERROR] " . now()->format('Y-m-d H:i:s') . " 駐輪場更新可能期間取得失敗 management_id=" . $managementId . ", error=" . $e->getMessage());
|
||||||
|
return collect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 運営元が取り扱う車種一覧を取得
|
||||||
|
*
|
||||||
|
* なぜ: マルチテナント対応のため、運営元ごとに表示する車種を可変にする
|
||||||
|
*
|
||||||
|
* @param int $managementId
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function getAvailableVehicles(int $managementId)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return DB::table('zone')
|
||||||
|
->join('park', 'zone.park_id', '=', 'park.park_id')
|
||||||
|
->leftJoin('psection', 'zone.psection_id', '=', 'psection.psection_id')
|
||||||
|
->where('park.management_id', $managementId)
|
||||||
|
->whereNotNull('psection.psection_subject')
|
||||||
|
->select('psection.psection_subject')
|
||||||
|
->distinct()
|
||||||
|
->orderByRaw("FIELD(psection.psection_subject, '自転車', '原付', '自動二輪', '自動車')")
|
||||||
|
->pluck('psection_subject')
|
||||||
|
->toArray();
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
\Log::error("[ERROR] " . now()->format('Y-m-d H:i:s') . " 取り扱い車種取得失敗 management_id=" . $managementId . ", error=" . $e->getMessage());
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 駐輪場ごと・車種ごとの状態を計算
|
||||||
|
*
|
||||||
|
* なぜ: Bladeでのビジネスロジック実行を避け、Fat Controller回避のため事前計算
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Support\Collection $parks
|
||||||
|
* @param \Illuminate\Support\Collection $zones
|
||||||
|
* @param \Illuminate\Support\Collection $reserve
|
||||||
|
* @param \Illuminate\Support\Collection $parkGracePeriods
|
||||||
|
* @param array $availableVehicles
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
private function calculateVehicleStatus($parks, $zones, $reserve, $parkGracePeriods, $availableVehicles)
|
||||||
|
{
|
||||||
|
$now = \Carbon\Carbon::now();
|
||||||
|
|
||||||
|
foreach ($parks as $park) {
|
||||||
|
$park->vehicle_status = [];
|
||||||
|
|
||||||
|
foreach ($availableVehicles as $vehicle) {
|
||||||
|
$zonesForType = ($zones[$park->park_id] ?? collect())->where('psection_subject', $vehicle);
|
||||||
|
|
||||||
|
// 空き台数計算
|
||||||
|
$hasVacancy = false;
|
||||||
|
foreach ($zonesForType as $zone) {
|
||||||
|
$reserveCount = ($reserve[$park->park_id] ?? collect())
|
||||||
|
->where('psection_id', $zone->psection_id)
|
||||||
|
->where('ptype_id', $zone->ptype_id)
|
||||||
|
->count();
|
||||||
|
$vacancy = $zone->zone_tolerance - $zone->zone_number - $reserveCount;
|
||||||
|
if ($vacancy > 0) {
|
||||||
|
$hasVacancy = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 猶予期間判定
|
||||||
|
$grace = $parkGracePeriods[$park->park_id] ?? null;
|
||||||
|
$inGrace = $this->isInGracePeriod($grace, $now);
|
||||||
|
|
||||||
|
// 状態判定
|
||||||
|
if ($zonesForType->isEmpty() || !$grace) {
|
||||||
|
$park->vehicle_status[$vehicle] = 'none';
|
||||||
|
} elseif ($inGrace && $hasVacancy) {
|
||||||
|
$park->vehicle_status[$vehicle] = 'available';
|
||||||
|
} elseif (!$inGrace) {
|
||||||
|
$park->vehicle_status[$vehicle] = 'out_of_period';
|
||||||
|
} elseif (!$hasVacancy) {
|
||||||
|
$park->vehicle_status[$vehicle] = 'waiting';
|
||||||
|
} else {
|
||||||
|
$park->vehicle_status[$vehicle] = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $parks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 猶予期間内かどうかを判定
|
||||||
|
*
|
||||||
|
* なぜ: 複雑な日時判定ロジックを分離し、可読性向上
|
||||||
|
*
|
||||||
|
* @param object|null $grace
|
||||||
|
* @param \Carbon\Carbon $now
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function isInGracePeriod($grace, $now)
|
||||||
|
{
|
||||||
|
if (!$grace) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// バリデーション
|
||||||
|
if (
|
||||||
|
!is_numeric($grace->update_grace_period_start_date) ||
|
||||||
|
!preg_match('/^\d{1,2}:\d{2}$/', $grace->update_grace_period_start_time) ||
|
||||||
|
!is_numeric($grace->update_grace_period_end_date) ||
|
||||||
|
!preg_match('/^\d{1,2}:\d{2}$/', $grace->update_grace_period_end_time)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$year = $now->year;
|
||||||
|
$month = $now->month;
|
||||||
|
$startDay = (int)$grace->update_grace_period_start_date;
|
||||||
|
$endDay = (int)$grace->update_grace_period_end_date;
|
||||||
|
|
||||||
|
if ($startDay > $endDay) {
|
||||||
|
// 月またぎ(例: 25日~5日)
|
||||||
|
$prevMonth = $now->copy()->subMonth();
|
||||||
|
$startPrev = \Carbon\Carbon::createFromFormat('Y-m-d H:i', sprintf('%04d-%02d-%02d %s', $prevMonth->year, $prevMonth->month, $startDay, $grace->update_grace_period_start_time));
|
||||||
|
$endCurr = \Carbon\Carbon::createFromFormat('Y-m-d H:i', sprintf('%04d-%02d-%02d %s', $year, $month, $endDay, $grace->update_grace_period_end_time));
|
||||||
|
|
||||||
|
$startCurr = \Carbon\Carbon::createFromFormat('Y-m-d H:i', sprintf('%04d-%02d-%02d %s', $year, $month, $startDay, $grace->update_grace_period_start_time));
|
||||||
|
$nextMonth = $month == 12 ? 1 : $month + 1;
|
||||||
|
$nextYear = $month == 12 ? $year + 1 : $year;
|
||||||
|
$endNext = \Carbon\Carbon::createFromFormat('Y-m-d H:i', sprintf('%04d-%02d-%02d %s', $nextYear, $nextMonth, $endDay, $grace->update_grace_period_end_time));
|
||||||
|
|
||||||
|
return $now->between($startPrev, $endCurr) || $now->between($startCurr, $endNext);
|
||||||
|
} else {
|
||||||
|
// 同月(例: 5日~25日)
|
||||||
|
$start = \Carbon\Carbon::createFromFormat('Y-m-d H:i', sprintf('%04d-%02d-%02d %s', $year, $month, $startDay, $grace->update_grace_period_start_time));
|
||||||
|
$end = \Carbon\Carbon::createFromFormat('Y-m-d H:i', sprintf('%04d-%02d-%02d %s', $year, $month, $endDay, $grace->update_grace_period_end_time));
|
||||||
|
|
||||||
|
return $now->between($start, $end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function regulationCheck(Request $request)
|
public function regulationCheck(Request $request)
|
||||||
{
|
{
|
||||||
// GETパラメータを取得
|
// GETパラメータを取得
|
||||||
|
|||||||
@ -17,7 +17,6 @@ table.tablesorter tfoot tr th {
|
|||||||
}
|
}
|
||||||
|
|
||||||
table.tablesorter thead tr .header {
|
table.tablesorter thead tr .header {
|
||||||
background-image: url(bg.gif);
|
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: center right;
|
background-position: center right;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -34,14 +33,6 @@ table.tablesorter tbody tr.odd td {
|
|||||||
background-color: #F0F0F6;
|
background-color: #F0F0F6;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.tablesorter thead tr .headerSortUp {
|
|
||||||
background-image: url(asc.gif);
|
|
||||||
}
|
|
||||||
|
|
||||||
table.tablesorter thead tr .headerSortDown {
|
|
||||||
background-image: url(desc.gif);
|
|
||||||
}
|
|
||||||
|
|
||||||
table.tablesorter thead tr .headerSortDown,
|
table.tablesorter thead tr .headerSortDown,
|
||||||
table.tablesorter thead tr .headerSortUp {
|
table.tablesorter thead tr .headerSortUp {
|
||||||
background-color: #8dbdd8;
|
background-color: #8dbdd8;
|
||||||
|
|||||||
@ -115,17 +115,26 @@ $(function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 駐輪場詳細ポップアップ
|
// 駐輪場詳細ポップアップ
|
||||||
$(document).on('click', '.btn-popup', function () {
|
$(document).on('click', '.btn-popup', function (e) {
|
||||||
var parkId = $(this).data('park-id');
|
e.preventDefault();
|
||||||
|
const url = $(this).data('url');
|
||||||
|
|
||||||
|
// data-url が存在しない場合はエラー
|
||||||
|
if (!url) {
|
||||||
|
console.error('data-url属性が設定されていません');
|
||||||
|
alert('URLが取得できませんでした。');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: '/api/park-detail/' + parkId,
|
url: url,
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
success: function (data) {
|
success: function (response) {
|
||||||
$('#modalArea').html(data.html); // モーダル全体を挿入
|
$('#modalArea').html(response.html);
|
||||||
$('#parkDetailModal').modal('show'); // モーダルを表示
|
$('#popup-modal').modal('show');
|
||||||
},
|
},
|
||||||
error: function () {
|
error: function () {
|
||||||
alert('詳細情報の取得に失敗しました');
|
alert('詳細情報の取得に失敗しました。');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/typicons/2.0.9/typicons.css" rel="stylesheet">
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/typicons/2.0.9/typicons.css" rel="stylesheet">
|
||||||
<link href="https://fonts.googleapis.com/earlyaccess/roundedmplus1c.css" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/earlyaccess/roundedmplus1c.css" rel="stylesheet">
|
||||||
<link href="{{ asset('assets/css/mypage/slick.css') }}" rel="stylesheet">
|
<link href="{{ asset('assets/css/mypage/slick.css') }}" rel="stylesheet">
|
||||||
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick-theme.css"/>
|
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick-theme.css" />
|
||||||
<link rel="stylesheet" href="{{ asset('assets/css/mypage/font-awesome.min.css') }}">
|
<link rel="stylesheet" href="{{ asset('assets/css/mypage/font-awesome.min.css') }}">
|
||||||
<link href="{{ asset('assets/css/mypage/bootstrap.min.css') }}" rel="stylesheet">
|
<link href="{{ asset('assets/css/mypage/bootstrap.min.css') }}" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="{{ asset('assets/css/mypage/picker.min.css') }}">
|
<link rel="stylesheet" href="{{ asset('assets/css/mypage/picker.min.css') }}">
|
||||||
@ -18,6 +18,7 @@
|
|||||||
<link href="{{ asset('assets/css/mypage/style.css') }}" rel="stylesheet">
|
<link href="{{ asset('assets/css/mypage/style.css') }}" rel="stylesheet">
|
||||||
<link href="{{ asset('assets/css/mypage/jquery-confirm.min.css') }}" rel="stylesheet">
|
<link href="{{ asset('assets/css/mypage/jquery-confirm.min.css') }}" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-confirm/3.3.4/jquery-confirm.min.css">
|
||||||
@yield('head')
|
@yield('head')
|
||||||
<style>
|
<style>
|
||||||
#main-news.jumbotron {
|
#main-news.jumbotron {
|
||||||
@ -49,6 +50,20 @@
|
|||||||
<script src="{{ asset('assets/js/vendor/jquery.tablesorter/jquery.tablesorter.min.js') }}" type="text/javascript"></script>
|
<script src="{{ asset('assets/js/vendor/jquery.tablesorter/jquery.tablesorter.min.js') }}" type="text/javascript"></script>
|
||||||
<script src="{{ asset('assets/js/commons.js') }}"></script>
|
<script src="{{ asset('assets/js/commons.js') }}"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-confirm/3.3.4/jquery-confirm.min.js"></script>
|
||||||
|
<script>
|
||||||
|
$(document).ready(function() {
|
||||||
|
// モーダルを閉じる前にフォーカスを解除
|
||||||
|
$('.modal').on('hide.bs.modal', function(e) {
|
||||||
|
$(this).find(':focus').blur();
|
||||||
|
});
|
||||||
|
|
||||||
|
// モーダルが完全に閉じた後、body にフォーカスを戻す
|
||||||
|
$('.modal').on('hidden.bs.modal', function() {
|
||||||
|
$('body').focus();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@yield('scripts')
|
@yield('scripts')
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
@extends('layouts.app')
|
@extends('layouts.app')
|
||||||
|
@section('title', $isRegularContract ? '空き駐輪場を確認する-新規定期契約 | So-Manager' : '駐輪場選択-駐輪場検索 | So-Manager')
|
||||||
@section('content')
|
@section('content')
|
||||||
<main>
|
<main>
|
||||||
<header class="alert alert-success">
|
<header class="title-header">
|
||||||
@if($isRegularContract)
|
@if($isRegularContract)
|
||||||
<h4 class="container">新規定期契約 > 空き駐輪場を確認する</h4>
|
新規定期契約 > 空き駐輪場を確認する
|
||||||
@else
|
@else
|
||||||
<h4 class="container">駐輪場検索 > 駐輪場選択</h4>
|
駐輪場検索 > 駐輪場選択
|
||||||
@endif
|
@endif
|
||||||
</header>
|
</header>
|
||||||
<section id="" class="container mt20 mb20">
|
<section id="" class="container mt20 mb20">
|
||||||
@ -20,11 +21,11 @@
|
|||||||
<div class="w-100 alert alert-success">
|
<div class="w-100 alert alert-success">
|
||||||
<h6><a class="text-success" data-toggle="collapse" href="#search-option" role="button"
|
<h6><a class="text-success" data-toggle="collapse" href="#search-option" role="button"
|
||||||
aria-expanded="false" aria-controls="search-option">絞込み条件を追加する</a></h6>
|
aria-expanded="false" aria-controls="search-option">絞込み条件を追加する</a></h6>
|
||||||
<div class="collapse row" id="search-option">
|
<div class="collapse row show" id="search-option">
|
||||||
<div class="col-3">市町村名</div>
|
<div class="col-3">市区町村名</div>
|
||||||
<div class="col-9 mb10">
|
<div class="col-9 mb10">
|
||||||
<select id="city-select" name="city_id" class="form-control form-control-lg" onchange="this.form.submit()">
|
<select id="city-select" name="city_id" class="form-control form-control-lg" onchange="this.form.submit()">
|
||||||
<option value="">市町村を選択してください</option>
|
<option value="">市区町村を選択してください</option>
|
||||||
@foreach($cities as $city)
|
@foreach($cities as $city)
|
||||||
<option value="{{ $city->city_id }}" @if(request('city_id')==$city->city_id) selected @endif>{{ $city->city_name }}</option>
|
<option value="{{ $city->city_id }}" @if(request('city_id')==$city->city_id) selected @endif>{{ $city->city_name }}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
@ -56,84 +57,35 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="header" style="cursor:default; pointer-events: none; background-color: #d4edda !important;">駐輪場名</th>
|
<th class="header" style="cursor:default; pointer-events: none; background-color: #d4edda !important;">駐輪場名</th>
|
||||||
<th class="header" style="cursor:default; pointer-events: none;">市町村名</th>
|
<th class="header" style="cursor:default; pointer-events: none;">市区町村名</th>
|
||||||
<th class="header" style="cursor:default; pointer-events: none;">駅名</th>
|
<th class="header" style="cursor:default; pointer-events: none;">駅名</th>
|
||||||
<th class="header" style="cursor:default; pointer-events: none;">自転車</th>
|
@foreach($available_vehicles as $vehicle)
|
||||||
<th class="header" style="cursor:default; pointer-events: none;">原付</th>
|
<th class="header" style="cursor:default; pointer-events: none;">{{ $vehicle }}</th>
|
||||||
<th class="header" style="cursor:default; pointer-events: none;">自動二輪</th>
|
@endforeach
|
||||||
<th class="header" style="cursor:default; pointer-events: none;">自動車</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@forelse($parks_table as $row)
|
@forelse($parks_table as $row)
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="javascript:void(0);" class="btn-popup text-primary" data-park-id="{{ $row->park_id }}">
|
<td><a href="javascript:void(0);"
|
||||||
|
class="btn-popup text-primary"
|
||||||
|
data-park-id="{{ $row->park_id }}"
|
||||||
|
data-url="{{ url(session('management')->management_code . '/api/park-detail/' . $row->park_id) }}">
|
||||||
{{ $row->park_name }}
|
{{ $row->park_name }}
|
||||||
</a></td>
|
</a></td>
|
||||||
<td>{{ $row->city_name }}</td>
|
<td>{{ $row->city_name }}</td>
|
||||||
<td>{{ $row->station_neighbor_station }}</td>
|
<td>{{ $row->station_neighbor_station }}</td>
|
||||||
{{-- 自転車・原付・自動二輪・自動車列 --}}
|
@foreach($available_vehicles as $vehicle)
|
||||||
@foreach(['自転車', '原付', '自動二輪', '自動車'] as $vehicle)
|
|
||||||
<td>
|
<td>
|
||||||
@php
|
@php
|
||||||
$zonesForType = ($zones[$row->park_id] ?? collect())->where('psection_subject', $vehicle);
|
$status = $row->vehicle_status[$vehicle] ?? 'none';
|
||||||
// 空き台数計算
|
|
||||||
$hasVacancy = false;
|
|
||||||
foreach ($zonesForType as $zone) {
|
|
||||||
$reserveCount = ($reserve[$row->park_id] ?? collect())
|
|
||||||
->where('psection_id', $zone->psection_id)
|
|
||||||
->where('ptype_id', $zone->ptype_id)
|
|
||||||
->count();
|
|
||||||
$vacancy = $zone->zone_tolerance - $zone->zone_number - $reserveCount;
|
|
||||||
if ($vacancy > 0) {
|
|
||||||
$hasVacancy = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 猶予期間判定
|
|
||||||
$grace = $city_grace_periods[$row->city_id] ?? null;
|
|
||||||
$gracePeriodValid =
|
|
||||||
$grace &&
|
|
||||||
is_numeric($grace->update_grace_period_start_date) &&
|
|
||||||
preg_match('/^\d{1,2}:\d{2}$/', $grace->update_grace_period_start_time) &&
|
|
||||||
is_numeric($grace->update_grace_period_end_date) &&
|
|
||||||
preg_match('/^\d{1,2}:\d{2}$/', $grace->update_grace_period_end_time);
|
|
||||||
|
|
||||||
$inGrace = false;
|
|
||||||
if ($gracePeriodValid) {
|
|
||||||
$now = \Carbon\Carbon::now();
|
|
||||||
$year = $now->year;
|
|
||||||
$month = $now->month;
|
|
||||||
$startDay = (int)$grace->update_grace_period_start_date;
|
|
||||||
$endDay = (int)$grace->update_grace_period_end_date;
|
|
||||||
if ($startDay > $endDay) {
|
|
||||||
// 月またぎ
|
|
||||||
// 前月の開始日~今月の終了日
|
|
||||||
$prevMonth = $now->copy()->subMonth();
|
|
||||||
$startPrev = \Carbon\Carbon::createFromFormat('Y-m-d H:i', sprintf('%04d-%02d-%02d %s', $prevMonth->year, $prevMonth->month, $startDay, $grace->update_grace_period_start_time));
|
|
||||||
$endCurr = \Carbon\Carbon::createFromFormat('Y-m-d H:i', sprintf('%04d-%02d-%02d %s', $year, $month, $endDay, $grace->update_grace_period_end_time));
|
|
||||||
// 今月の開始日~翌月の終了日
|
|
||||||
$startCurr = \Carbon\Carbon::createFromFormat('Y-m-d H:i', sprintf('%04d-%02d-%02d %s', $year, $month, $startDay, $grace->update_grace_period_start_time));
|
|
||||||
$nextMonth = $month == 12 ? 1 : $month + 1;
|
|
||||||
$nextYear = $month == 12 ? $year + 1 : $year;
|
|
||||||
$endNext = \Carbon\Carbon::createFromFormat('Y-m-d H:i', sprintf('%04d-%02d-%02d %s', $nextYear, $nextMonth, $endDay, $grace->update_grace_period_end_time));
|
|
||||||
$inGrace = $now->between($startPrev, $endCurr) || $now->between($startCurr, $endNext);
|
|
||||||
} else {
|
|
||||||
// 同月
|
|
||||||
$start = \Carbon\Carbon::createFromFormat('Y-m-d H:i', sprintf('%04d-%02d-%02d %s', $year, $month, $startDay, $grace->update_grace_period_start_time));
|
|
||||||
$end = \Carbon\Carbon::createFromFormat('Y-m-d H:i', sprintf('%04d-%02d-%02d %s', $year, $month, $endDay, $grace->update_grace_period_end_time));
|
|
||||||
$inGrace = $now->between($start, $end);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@endphp
|
@endphp
|
||||||
@if ($zonesForType->isNotEmpty() && $gracePeriodValid)
|
@if($status === 'available')
|
||||||
@if ($hasVacancy && $inGrace)
|
<button class="btn btn-block btn-sm btn-outline-success btn_82-table btn-popup" data-park-id="{{ $row->park_id }}" data-url="{{ url(session('management')->management_code . '/api/park-detail/' . $row->park_id) }}">定期契約</button>
|
||||||
<button class="btn btn-block btn-sm btn-outline-success btn_82-table btn-popup" data-park-id="{{ $row->park_id }}">定期契約</button>
|
@elseif($status === 'out_of_period')
|
||||||
@elseif (!$inGrace)
|
<button class="btn btn-block btn-sm btn-outline-danger btn_103-table btn-popup" data-park-id="{{ $row->park_id }}" data-url="{{ url(session('management')->management_code . '/api/park-detail/' . $row->park_id) }}">販売期間外(予約可)</button>
|
||||||
<button class="btn btn-block btn-sm btn-outline-danger btn_103-table btn-popup" data-park-id="{{ $row->park_id }}">販売期間外</button>
|
@elseif($status === 'waiting')
|
||||||
@elseif (!$hasVacancy && $inGrace)
|
<button class="btn btn-block btn-sm btn-outline-danger btn_103-table btn-popup" data-park-id="{{ $row->park_id }}" data-url="{{ url(session('management')->management_code . '/api/park-detail/' . $row->park_id) }}">空き待ち予約</button>
|
||||||
<button class="btn btn-block btn-sm btn-outline-danger btn_103-table btn-popup" data-park-id="{{ $row->park_id }}">空き待ち申込</button>
|
|
||||||
@endif
|
|
||||||
@else
|
@else
|
||||||
<span class="text-muted"></span>
|
<span class="text-muted"></span>
|
||||||
@endif
|
@endif
|
||||||
@ -142,7 +94,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
@empty
|
@empty
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="7" class="text-center">該当する駐輪場はありません。</td>
|
<td colspan="{{ 3 + count($available_vehicles) }}" class="text-center">該当する駐輪場はありません。</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforelse
|
@endforelse
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -180,11 +132,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
<div id="modalArea"></div>
|
<div class="modal fade" id="popup-modal" tabindex="-1" role="dialog">
|
||||||
<div class="modal fade" id="popup-modal" tabindex="-1">
|
<div class="modal-dialog modal-lg">
|
||||||
<div class="modal-dialog">
|
<div class="modal-content" id="modalArea">
|
||||||
<div class="modal-content" id="popup-content">
|
<!-- Ajaxで取得したHTMLがここに挿入される -->
|
||||||
<!-- Ajaxで詳細HTMLを挿入 -->
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,124 +1,115 @@
|
|||||||
<!-- Bootstrapモーダル -->
|
<!-- Bootstrapモーダル -->
|
||||||
<div class="modal fade" id="parkDetailModal" tabindex="-1" aria-labelledby="parkDetailLabel" aria-hidden="true">
|
<div class="modal-header">
|
||||||
<div class="modal-dialog modal-lg">
|
<h5 class="modal-title" id="parkDetailLabel">{{ $park->park_name }}</h5>
|
||||||
<div class="modal-content">
|
<button type="button" class="close" data-dismiss="modal" aria-label="閉じる">
|
||||||
<div class="modal-header">
|
<span aria-hidden="true">×</span>
|
||||||
<h5 class="modal-title" id="parkDetailLabel">{{ $park->park_name }}</h5>
|
</button>
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="閉じる">
|
</div>
|
||||||
<span aria-hidden="true">×</span>
|
<div class="modal-body">
|
||||||
</button>
|
<!-- Googleマップ埋め込み -->
|
||||||
</div>
|
<div style="width:100%; height:350px;">
|
||||||
<div class="modal-body">
|
<iframe
|
||||||
<!-- Googleマップ埋め込み -->
|
width="100%"
|
||||||
<div style="width:100%; height:350px;">
|
height="350"
|
||||||
<iframe
|
frameborder="0"
|
||||||
width="100%"
|
style="border:0"
|
||||||
height="350"
|
src="https://www.google.com/maps?q={{ $park->park_latitude }},{{ $park->park_longitude }}&hl=ja&z=16&output=embed"
|
||||||
frameborder="0"
|
allowfullscreen>
|
||||||
style="border:0"
|
</iframe>
|
||||||
src="https://www.google.com/maps?q={{ $park->park_latitude }},{{ $park->park_longitude }}&hl=ja&z=16&output=embed"
|
</div>
|
||||||
allowfullscreen>
|
<!-- 駐輪場情報 -->
|
||||||
</iframe>
|
<div class="mt-3 small">
|
||||||
</div>
|
{{ $park->park_adrs }}
|
||||||
<!-- 駐輪場情報 -->
|
<span class="d-inline-block" style="margin-top:0.5em;"></span>
|
||||||
<div class="mt-3 small">
|
<span>
|
||||||
{{ $park->park_adrs }}
|
【標準収容台数】
|
||||||
<span class="d-inline-block" style="margin-top:0.5em;"></span>
|
@foreach($zoneStandardSum as $type => $count)
|
||||||
<span>
|
{{ $type }}:{{ $count }}台
|
||||||
【標準収容台数】
|
@endforeach
|
||||||
@foreach($zoneStandardSum as $type => $count)
|
</span>
|
||||||
{{ $type }}:{{ $count }}台
|
</div>
|
||||||
@endforeach
|
<div class="mt-3">
|
||||||
</span>
|
<span>{{ $park->price_memo }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-3">
|
<!-- 空き台数・契約情報 -->
|
||||||
<span>{{ $park->price_memo }}</span>
|
<div class="mt-3">
|
||||||
</div>
|
@php
|
||||||
<!-- 空き台数・契約情報 -->
|
$zonesByPtype = $zones->groupBy('ptype_id');
|
||||||
<div class="mt-3">
|
@endphp
|
||||||
@php
|
@foreach($zonesByPtype as $ptypeId => $zonesGroup)
|
||||||
$zonesByPtype = $zones->groupBy('ptype_id');
|
<div class="mb-3">
|
||||||
@endphp
|
<strong>{{ $zonesGroup->first()->ptype_subject }}{{ $zonesGroup->first()->zone_name }}</strong>
|
||||||
@foreach($zonesByPtype as $ptypeId => $zonesGroup)
|
<div style="display: flex; gap: 1em;">
|
||||||
<div class="mb-3">
|
@foreach($zonesGroup as $zone)
|
||||||
<strong>{{ $zonesGroup->first()->ptype_subject }}</strong>
|
@php
|
||||||
<div style="display: flex; gap: 1em;">
|
$vacant = $vacancyData[$zone->psection_id . '_' . $zone->ptype_subject] ?? 0;
|
||||||
@foreach($zonesGroup as $zone)
|
$grace = $parkGracePeriod ?? null;
|
||||||
@php
|
$now = \Carbon\Carbon::now();
|
||||||
$vacant = $vacancyData[$zone->psection_id . '_' . $zone->ptype_subject] ?? 0;
|
|
||||||
$grace = $city_grace_periods[$park->city_id] ?? null;
|
|
||||||
$now = \Carbon\Carbon::now();
|
|
||||||
|
|
||||||
// 猶予期間判定
|
// 猶予期間判定
|
||||||
$isGracePeriod = false;
|
$isGracePeriod = false;
|
||||||
if ($grace && $grace->update_grace_period_start_date && $grace->update_grace_period_start_time && $grace->update_grace_period_end_date && $grace->update_grace_period_end_time) {
|
if ($grace && $grace->update_grace_period_start_date && $grace->update_grace_period_start_time && $grace->update_grace_period_end_date && $grace->update_grace_period_end_time) {
|
||||||
$now = \Carbon\Carbon::now();
|
$now = \Carbon\Carbon::now();
|
||||||
$year = $now->year;
|
$year = $now->year;
|
||||||
$month = $now->month;
|
$month = $now->month;
|
||||||
$startDay = (int)$grace->update_grace_period_start_date;
|
$startDay = (int)$grace->update_grace_period_start_date;
|
||||||
$endDay = (int)$grace->update_grace_period_end_date;
|
$endDay = (int)$grace->update_grace_period_end_date;
|
||||||
$startTime = $grace->update_grace_period_start_time;
|
$startTime = $grace->update_grace_period_start_time;
|
||||||
$endTime = $grace->update_grace_period_end_time;
|
$endTime = $grace->update_grace_period_end_time;
|
||||||
|
|
||||||
if ($startDay > $endDay) {
|
if ($startDay > $endDay) {
|
||||||
// 月またぎ
|
// 月またぎ
|
||||||
// 前月の開始日~今月の終了日
|
// 前月の開始日~今月の終了日
|
||||||
$prevMonth = $now->copy()->subMonth();
|
$prevMonth = $now->copy()->subMonth();
|
||||||
$startPrev = \Carbon\Carbon::createFromFormat('Y-m-d H:i', sprintf('%04d-%02d-%02d %s', $prevMonth->year, $prevMonth->month, $startDay, $grace->update_grace_period_start_time));
|
$startPrev = \Carbon\Carbon::createFromFormat('Y-m-d H:i', sprintf('%04d-%02d-%02d %s', $prevMonth->year, $prevMonth->month, $startDay, $grace->update_grace_period_start_time));
|
||||||
$endCurr = \Carbon\Carbon::createFromFormat('Y-m-d H:i', sprintf('%04d-%02d-%02d %s', $year, $month, $endDay, $grace->update_grace_period_end_time));
|
$endCurr = \Carbon\Carbon::createFromFormat('Y-m-d H:i', sprintf('%04d-%02d-%02d %s', $year, $month, $endDay, $grace->update_grace_period_end_time));
|
||||||
// 今月の開始日~翌月の終了日
|
// 今月の開始日~翌月の終了日
|
||||||
$startCurr = \Carbon\Carbon::createFromFormat('Y-m-d H:i', sprintf('%04d-%02d-%02d %s', $year, $month, $startDay, $grace->update_grace_period_start_time));
|
$startCurr = \Carbon\Carbon::createFromFormat('Y-m-d H:i', sprintf('%04d-%02d-%02d %s', $year, $month, $startDay, $grace->update_grace_period_start_time));
|
||||||
$nextMonth = $month == 12 ? 1 : $month + 1;
|
$nextMonth = $month == 12 ? 1 : $month + 1;
|
||||||
$nextYear = $month == 12 ? $year + 1 : $year;
|
$nextYear = $month == 12 ? $year + 1 : $year;
|
||||||
$endNext = \Carbon\Carbon::createFromFormat('Y-m-d H:i', sprintf('%04d-%02d-%02d %s', $nextYear, $nextMonth, $endDay, $grace->update_grace_period_end_time));
|
$endNext = \Carbon\Carbon::createFromFormat('Y-m-d H:i', sprintf('%04d-%02d-%02d %s', $nextYear, $nextMonth, $endDay, $grace->update_grace_period_end_time));
|
||||||
$isGracePeriod = $now->between($startPrev, $endCurr) || $now->between($startCurr, $endNext);
|
$isGracePeriod = $now->between($startPrev, $endCurr) || $now->between($startCurr, $endNext);
|
||||||
} else {
|
} else {
|
||||||
// 同月
|
// 同月
|
||||||
$start = \Carbon\Carbon::createFromFormat('Y-m-d H:i', sprintf('%04d-%02d-%02d %s', $year, $month, $startDay, $grace->update_grace_period_start_time));
|
$start = \Carbon\Carbon::createFromFormat('Y-m-d H:i', sprintf('%04d-%02d-%02d %s', $year, $month, $startDay, $grace->update_grace_period_start_time));
|
||||||
$end = \Carbon\Carbon::createFromFormat('Y-m-d H:i', sprintf('%04d-%02d-%02d %s', $year, $month, $endDay, $grace->update_grace_period_end_time));
|
$end = \Carbon\Carbon::createFromFormat('Y-m-d H:i', sprintf('%04d-%02d-%02d %s', $year, $month, $endDay, $grace->update_grace_period_end_time));
|
||||||
$isGracePeriod = $now->between($start, $end);
|
$isGracePeriod = $now->between($start, $end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@endphp
|
@endphp
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
{{ $zone->psection_subject }}:空き {{ max(0, $vacant) }}台
|
{{ $zone->psection_subject }}:空き {{ max(0, $vacant) }}台
|
||||||
@if($isGracePeriod)
|
@if($isGracePeriod)
|
||||||
@if($vacant > 0)
|
@if($vacant > 0)
|
||||||
<button type="button" class="btn btn-success btn-sm btn-contract"
|
<button type="button" class="btn btn-success btn-sm btn-contract"
|
||||||
data-park-id="{{ $park->park_id }}"
|
data-park-id="{{ $park->park_id }}"
|
||||||
data-psection-id="{{ $zone->psection_id }}"
|
data-psection-id="{{ $zone->psection_id }}"
|
||||||
data-ptype-id="{{ $zone->ptype_id }}">
|
data-ptype-id="{{ $zone->ptype_id }}">
|
||||||
定期契約
|
定期契約
|
||||||
</button>
|
</button>
|
||||||
@else
|
@else
|
||||||
<button type="button" class="btn btn-danger btn-sm btn_103 btn-reserve"
|
<button type="button" class="btn btn-danger btn-sm btn_103 btn-reserve"
|
||||||
data-park-id="{{ $park->park_id }}"
|
data-park-id="{{ $park->park_id }}"
|
||||||
data-psection-id="{{ $zone->psection_id }}"
|
data-psection-id="{{ $zone->psection_id }}"
|
||||||
data-ptype-id="{{ $zone->ptype_id }}">
|
data-ptype-id="{{ $zone->ptype_id }}">
|
||||||
空き待ち申込
|
空き待ち予約
|
||||||
</button>
|
</button>
|
||||||
@endif
|
@endif
|
||||||
@else
|
@else
|
||||||
<button type="button" class="btn btn-danger btn-sm btn_103 btn-reserve"
|
<button type="button" class="btn btn-danger btn-sm btn_103 btn-reserve"
|
||||||
data-park-id="{{ $park->park_id }}"
|
data-park-id="{{ $park->park_id }}"
|
||||||
data-psection-id="{{ $zone->psection_id }}"
|
data-psection-id="{{ $zone->psection_id }}"
|
||||||
data-ptype-id="{{ $zone->ptype_id }}">
|
data-ptype-id="{{ $zone->ptype_id }}">
|
||||||
販売期間外
|
販売期間外(予約可)
|
||||||
</button>
|
</button>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
|
||||||
@endforeach
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endforeach
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
@endforeach
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">閉じる</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@endforeach
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- jQuery Confirm用CSS/JS(jQuery本体は既に読み込まれていれば不要) -->
|
<div class="modal-footer">
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-confirm/3.3.4/jquery-confirm.min.css">
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">閉じる</button>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-confirm/3.3.4/jquery-confirm.min.js"></script>
|
</div>
|
||||||
Loading…
Reference in New Issue
Block a user