310 lines
12 KiB
PHP
310 lines
12 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Controllers\Admin;
|
||
|
||
use Illuminate\Support\Facades\Schema;
|
||
use Illuminate\Http\Request;
|
||
use Illuminate\Support\Facades\DB;
|
||
use Illuminate\Support\Facades\Validator;
|
||
|
||
class ReservesController
|
||
{
|
||
/**
|
||
* 予約一覧
|
||
* - 基本表: reserve(r)
|
||
* - 付加情報: user(u), park(p)
|
||
* - 画面変数: $list, $sort, $sort_type(利用者マスタの書式に準拠)
|
||
*
|
||
* reserve テーブルの主な列:
|
||
* reserve_id, contract_id, user_id, park_id, price_parkplaceid, psection_id,
|
||
* reserve_date, reserve_start, reserve_end, reserve_cancelday, valid_flag, ope_id など
|
||
* (DDL は dump の通り)【turn12file6†L15-L37】
|
||
*/
|
||
public function list(Request $request)
|
||
{
|
||
// ── 並び順(既定: reserve_id DESC)──────────────────────────────
|
||
$sort = $request->input('sort', 'reserve_id');
|
||
$sortType = strtolower($request->input('sort_type', 'desc')) === 'asc' ? 'asc' : 'desc';
|
||
|
||
// ── 絞り込み(必要最低限:利用者/駐輪場/期間)──────────────────
|
||
$userId = trim((string) $request->input('user_id', ''));
|
||
$parkId = trim((string) $request->input('park_id', ''));
|
||
$fromDt = $request->input('reserve_date_from', '');
|
||
$toDt = $request->input('reserve_date_to', '');
|
||
$keyword = trim((string) $request->input('keyword', '')); // 利用者名かな など
|
||
|
||
// ── クエリ構築 ────────────────────────────────────────────────
|
||
$q = DB::table('reserve as r')
|
||
->leftJoin('user as u', 'u.user_id', '=', 'r.user_id') // user: user_name, user_phonetic 等【turn12file9†L26-L34】
|
||
->leftJoin('park as p', 'p.park_id', '=', 'r.park_id') // park: park_name 等【turn12file4†L17-L25】
|
||
->select([
|
||
'r.reserve_id',
|
||
'r.contract_id',
|
||
'r.user_id',
|
||
'r.park_id',
|
||
'r.price_parkplaceid',
|
||
'r.psection_id',
|
||
'r.reserve_date',
|
||
'r.reserve_start',
|
||
'r.reserve_end',
|
||
'r.reserve_cancelday',
|
||
'r.valid_flag',
|
||
'r.ope_id',
|
||
DB::raw('u.user_name as user_name'),
|
||
DB::raw('u.user_phonetic as user_phonetic'),
|
||
DB::raw('u.user_mobile as user_mobile'),
|
||
DB::raw('p.park_name as park_name'),
|
||
]);
|
||
|
||
if ($userId !== '')
|
||
$q->where('r.user_id', 'like', "%{$userId}%");
|
||
if ($parkId !== '')
|
||
$q->where('r.park_id', 'like', "%{$parkId}%");
|
||
|
||
if ($fromDt)
|
||
$q->whereDate('r.reserve_date', '>=', $fromDt);
|
||
if ($toDt)
|
||
$q->whereDate('r.reserve_date', '<=', $toDt);
|
||
|
||
if ($keyword !== '') {
|
||
$q->where(function ($w) use ($keyword) {
|
||
$w->where('u.user_name', 'like', "%{$keyword}%")
|
||
->orWhere('u.user_phonetic', 'like', "%{$keyword}%");
|
||
});
|
||
}
|
||
|
||
// ソート許可カラム(JOIN 先も含む)
|
||
$sortable = [
|
||
'reserve_id',
|
||
'contract_id',
|
||
'user_id',
|
||
'park_id',
|
||
'reserve_date',
|
||
'reserve_start',
|
||
'reserve_end',
|
||
'reserve_cancelday',
|
||
'valid_flag',
|
||
'ope_id',
|
||
'user_name',
|
||
'user_phonetic',
|
||
'user_mobile',
|
||
'park_name',
|
||
];
|
||
if (!in_array($sort, $sortable, true))
|
||
$sort = 'reserve_id';
|
||
|
||
$sortMap = [
|
||
'user_name' => 'u.user_name',
|
||
'user_phonetic' => 'u.user_phonetic',
|
||
'user_mobile' => 'u.user_mobile',
|
||
'park_name' => 'p.park_name',
|
||
];
|
||
$sortCol = $sortMap[$sort] ?? ('r.' . $sort);
|
||
|
||
$list = $q->orderBy($sortCol, $sortType)->paginate(50);
|
||
|
||
return view('admin.reserves.list', [
|
||
'list' => $list,
|
||
'sort' => $sort,
|
||
'sort_type' => $sortType,
|
||
// 入力保持
|
||
'user_id' => $userId,
|
||
'park_id' => $parkId,
|
||
'reserve_date_from' => $fromDt,
|
||
'reserve_date_to' => $toDt,
|
||
'keyword' => $keyword,
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* 予約追加(GET: 画面表示 / POST: 登録)
|
||
*/
|
||
public function add(Request $request)
|
||
{
|
||
if ($request->isMethod('get')) {
|
||
return view('admin.reserves.add');
|
||
}
|
||
|
||
// 予約の最低限バリデーション(必要に応じて追加)
|
||
$v = Validator::make($request->all(), [
|
||
'user_id' => ['required', 'integer'],
|
||
'park_id' => ['required', 'integer'],
|
||
'reserve_date' => ['nullable', 'date'],
|
||
'reserve_start' => ['nullable', 'date'],
|
||
'reserve_end' => ['nullable', 'date'],
|
||
], [], [
|
||
'user_id' => '利用者ID',
|
||
'park_id' => '駐輪場ID',
|
||
]);
|
||
|
||
if ($v->fails()) {
|
||
return back()->withErrors($v)->withInput();
|
||
}
|
||
|
||
DB::table('reserve')->insert([
|
||
'user_id' => (int) $request->input('user_id'),
|
||
'park_id' => (int) $request->input('park_id'),
|
||
'contract_id' => $request->input('contract_id'), // 任意:regular_contract と紐づける場合【turn12file7†L20-L28】
|
||
'price_parkplaceid' => $request->input('price_parkplaceid'),
|
||
'psection_id' => $request->input('psection_id'),
|
||
'reserve_date' => $request->input('reserve_date'),
|
||
'reserve_start' => $request->input('reserve_start'),
|
||
'reserve_end' => $request->input('reserve_end'),
|
||
'valid_flag' => $request->input('valid_flag'),
|
||
'ope_id' => $request->input('ope_id'),
|
||
'created_at' => now(),
|
||
'updated_at' => now(),
|
||
]);
|
||
|
||
return redirect()->route('reserves')->with('success', '予約を登録しました。');
|
||
}
|
||
|
||
/**
|
||
* 予約削除
|
||
*/
|
||
public function delete(Request $request)
|
||
{
|
||
|
||
$normalizeIds = function ($raw) {
|
||
|
||
if (is_string($raw)) {
|
||
$raw = explode(',', $raw);
|
||
}
|
||
if (is_array($raw) && count($raw) === 1 && is_string($raw[0]) && str_contains($raw[0], ',')) {
|
||
$raw = explode(',', $raw[0]);
|
||
}
|
||
$ids = array_map('intval', (array) $raw);
|
||
$ids = array_values(array_unique(array_filter($ids, fn($v) => $v > 0)));
|
||
return $ids;
|
||
};
|
||
|
||
if ($request->isMethod('get')) {
|
||
|
||
$ids = $normalizeIds($request->input('ids', []));
|
||
|
||
$rows = [];
|
||
if ($ids) {
|
||
$rows = DB::table('reserve as r')
|
||
->leftJoin('user as u', 'u.user_id', '=', 'r.user_id')
|
||
->leftJoin('park as p', 'p.park_id', '=', 'r.park_id')
|
||
->whereIn('r.reserve_id', $ids)
|
||
->select('r.*', 'u.user_name', 'p.park_name')
|
||
->get();
|
||
}
|
||
return view('admin.reserves.delete', compact('rows', 'ids'));
|
||
}
|
||
|
||
|
||
if ($request->post('confirmed')) {
|
||
$ids = $normalizeIds($request->input('ids', []));
|
||
if ($ids) {
|
||
$deleted = DB::table('reserve')->whereIn('reserve_id', $ids)->delete();
|
||
return redirect()->route('reserves')->with(
|
||
$deleted ? 'success' : 'warning',
|
||
$deleted ? "{$deleted} 件を削除しました。" : '対象が見つかりませんでした。'
|
||
);
|
||
}
|
||
}
|
||
|
||
return redirect()->route('reserves')->with('warning', '削除対象がありません。');
|
||
}
|
||
|
||
|
||
public function edit(Request $request, $reserve_id)
|
||
{
|
||
$id = (int) $reserve_id;
|
||
|
||
// 取得レコード(無ければ404)
|
||
$row = DB::table('reserve')->where('reserve_id', $id)->first();
|
||
if (!$row) {
|
||
abort(404);
|
||
}
|
||
|
||
// POST: 更新処理(※reserveテーブルに確実にある列だけ更新)
|
||
if ($request->isMethod('post')) {
|
||
$v = Validator::make($request->all(), [
|
||
'user_id' => ['required', 'integer'],
|
||
'park_id' => ['required', 'integer'],
|
||
'reserve_date' => ['nullable', 'date'],
|
||
'reserve_start' => ['nullable', 'date'],
|
||
'reserve_end' => ['nullable', 'date'],
|
||
], [], [
|
||
'user_id' => '利用者ID',
|
||
'park_id' => '駐輪場ID',
|
||
]);
|
||
|
||
if ($v->fails()) {
|
||
return back()->withErrors($v)->withInput();
|
||
}
|
||
|
||
$data = [
|
||
'contract_id' => $request->input('contract_id'),
|
||
'user_id' => (int) $request->input('user_id'),
|
||
'park_id' => (int) $request->input('park_id'),
|
||
'price_parkplaceid' => $request->input('price_parkplaceid'),
|
||
'psection_id' => $request->input('psection_id'),
|
||
'reserve_date' => $request->input('reserve_date'),
|
||
'reserve_start' => $request->input('reserve_start'),
|
||
'reserve_end' => $request->input('reserve_end'),
|
||
'valid_flag' => $request->input('valid_flag'),
|
||
'ope_id' => $request->input('ope_id'),
|
||
'updated_at' => now(),
|
||
];
|
||
DB::table('reserve')->where('reserve_id', $id)->update($data);
|
||
|
||
return redirect()->route('reserves')->with('success', '予約を更新しました。');
|
||
}
|
||
|
||
// GET: 編集画面表示用の各種プルダウン(存在するテーブルだけ読む)
|
||
$userOptions = DB::table('user')
|
||
->orderBy('user_id', 'asc')
|
||
->limit(5000)
|
||
->pluck(DB::raw("concat(user_id, ' ', user_name)"), 'user_id')
|
||
->toArray();
|
||
|
||
$parkOptions = DB::table('park')
|
||
->orderBy('park_id', 'asc')
|
||
->limit(5000)
|
||
->pluck(DB::raw("concat(park_id, ' ', park_name)"), 'park_id')
|
||
->toArray();
|
||
|
||
$userTypeOptions = Schema::hasTable('usertype')
|
||
? DB::table('usertype')->orderBy('user_categoryid')
|
||
->pluck('print_name', 'user_categoryid')->toArray()
|
||
: [];
|
||
|
||
$parkplaceOptions = Schema::hasTable('price_parkplace')
|
||
? DB::table('price_parkplace')->orderBy('price_parkplaceid')
|
||
->pluck('price_parkplaceid', 'price_parkplaceid')->toArray()
|
||
: [];
|
||
|
||
$psectionOptions = Schema::hasTable('psection')
|
||
? DB::table('psection')->orderBy('psection_id')
|
||
->pluck(
|
||
Schema::hasColumn('psection', 'psection_name') ? 'psection_name' : 'psection_id',
|
||
'psection_id'
|
||
)->toArray()
|
||
: [];
|
||
|
||
$ptypeOptions = Schema::hasTable('ptype')
|
||
? DB::table('ptype')->orderBy('ptype_id')
|
||
->pluck(
|
||
Schema::hasColumn('ptype', 'ptype_name') ? 'ptype_name' : 'ptype_id',
|
||
'ptype_id'
|
||
)->toArray()
|
||
: [];
|
||
|
||
|
||
return view('admin.reserves.edit', compact(
|
||
'row',
|
||
'userOptions',
|
||
'parkOptions',
|
||
'userTypeOptions',
|
||
'parkplaceOptions',
|
||
'psectionOptions',
|
||
'ptypeOptions'
|
||
));
|
||
}
|
||
|
||
}
|