join('regular_contract as rc', 'rc.user_categoryid', '=', 't.user_categoryid') ->select('t.user_categoryid', 't.usertype_subject1', 't.usertype_subject2', 't.usertype_subject3') ->groupBy('t.user_categoryid', 't.usertype_subject1', 't.usertype_subject2', 't.usertype_subject3') ->orderBy('t.user_categoryid', 'asc') ->get() ->mapWithKeys(function ($row) { $label = collect([ $row->usertype_subject1 ?? '', $row->usertype_subject2 ?? '', $row->usertype_subject3 ?? '', ])->filter(fn ($v) => $v !== '')->implode('/'); return [$row->user_categoryid => $label !== '' ? $label : (string) $row->user_categoryid]; }) ->toArray(); } private function buildParkOptions(): array { return Park::query() ->join('regular_contract as rc', 'rc.park_id', '=', 'park.park_id') ->select('park.park_id', 'park.park_name') ->groupBy('park.park_id', 'park.park_name') ->orderBy('park.park_id', 'asc') ->get() ->mapWithKeys(fn ($park) => [ $park->park_id => $park->park_name ?: (string) $park->park_id, ]) ->toArray(); } /** * datetime-local から受け取った値を Y-m-d H:i:s へ正規化 */ private function normalizeDateTimeInput(?string $value, bool $endOfMinute = false): ?string { if ($value === null) { return null; } $value = trim($value); if ($value === '') { return null; } $value = str_replace('T', ' ', $value); if (strlen($value) === 16) { $value .= ':00'; } try { $dt = Carbon::parse($value); if ($endOfMinute) { $dt = $dt->endOfMinute(); } return $dt->format('Y-m-d H:i:s'); } catch (\Throwable $e) { return null; } } /** * 名寄フリガナ検索用:全角カナへ統一し空白除去 */ private function normalizePhoneticKeyword(?string $value): ?string { if ($value === null) { return null; } $value = trim((string) $value); if ($value === '') { return null; } $value = mb_convert_kana($value, 'KVCS'); return str_replace([' ', ' '], '', $value); } /** * 定期契約一覧 * - ベース表: regular_contract(rc) * - 付加情報: user(u), usertype(t), park(p) * - 画面変数: $list, $sort, $sort_type(既存に合わせる) */ public function list(Request $request) { if ($request->isMethod('post')) { $postParams = $request->except(['_token']); $queryParams = $request->query(); return redirect()->route('regularcontracts', array_merge($queryParams, $postParams)); } $params = $request->query(); // ===== ソート(既定: contract_id ASC)===== $sort = $params['sort'] ?? 'contract_id'; $sortType = strtolower($params['sort_type'] ?? 'asc') === 'desc' ? 'desc' : 'asc'; // ===== 絞り込み(テキスト系)===== $contract_qr_id = trim((string) ($params['contract_qr_id'] ?? '')); $user_id = trim((string) ($params['user_id'] ?? '')); $user_tag_serial = trim((string) ($params['user_tag_serial'] ?? '')); $park_id = trim((string) ($params['park_id'] ?? '')); $selectedParkId = trim((string) ($params['selected_park_id'] ?? '')); $user_phonetic = trim((string) ($params['user_phonetic'] ?? '')); $phone = trim((string) ($params['phone'] ?? '')); $email = trim((string) ($params['email'] ?? '')); $user_categoryid = trim((string) ($params['user_categoryid'] ?? '')); $park_name_kw = trim((string) ($params['park_name'] ?? '')); $zone_keyword = trim((string) ($params['zone_keyword'] ?? '')); $zone_name = trim((string) ($params['zone_name'] ?? '')); $merge_phonetic_input = $params['merge_phonetic'] ?? ''; $merge_phonetic = trim((string) $merge_phonetic_input); $merge_phonetic_normalized = $this->normalizePhoneticKeyword($merge_phonetic); $has_address = $params['has_address'] ?? ''; $workRecordFilter = (string) ($params['work_record'] ?? '0'); if (!in_array($workRecordFilter, ['0', '1', '2'], true)) { $workRecordFilter = '0'; } // ===== 絞り込み(日付範囲)===== $reserve_from = $params['reserve_date_from'] ?? ''; $reserve_to = $params['reserve_date_to'] ?? ''; $created_from = $params['contract_created_from'] ?? ''; $created_to = $params['contract_created_to'] ?? ''; $updated_from = $params['contract_updated_from'] ?? ''; $updated_to = $params['contract_updated_to'] ?? ''; $canceled_from = $params['contract_canceled_from'] ?? ''; $canceled_to = $params['contract_canceled_to'] ?? ''; $receipt_delivery_from = $params['receipt_delivery_from'] ?? ''; $receipt_delivery_to = $params['receipt_delivery_to'] ?? ''; $contract_valid_months = $params['contract_valid_months'] ?? ''; // ===== 列挙(全て/0/1)===== $contract_flag = $params['contract_flag'] ?? ''; $contract_permission = $params['contract_permission'] ?? ''; $tag_qr_flag = $params['tag_qr_flag'] ?? ''; $updateFlagFilter = (string) ($params['update_flag'] ?? '0'); if (!in_array($updateFlagFilter, ['0', '1', '2'], true)) { $updateFlagFilter = '0'; } $contract_cancel_flag = $params['contract_cancel_flag'] ?? ''; // ===== クエリ(結合込み)===== $q = DB::table('regular_contract as rc') ->leftJoin('user as u', 'u.user_id', '=', 'rc.user_id') ->leftJoin('usertype as t', 't.user_categoryid', '=', 'rc.user_categoryid') ->leftJoin('park as p', 'p.park_id', '=', 'rc.park_id') ->leftJoin('zone as z', 'z.zone_id', '=', 'rc.zone_id') ->select([ 'rc.*', 'u.user_seq', 'u.user_name', 'u.user_phonetic', 'u.user_mobile', 'u.user_homephone', 'u.user_primemail', 'u.user_regident_zip', 'u.user_tag_serial', DB::raw('t.print_name as usertype_name'), 't.usertype_subject1', 't.usertype_subject2', 't.usertype_subject3', DB::raw('p.park_name as park_name'), DB::raw('z.zone_name as zone_name'), ]); // ===== LIKE / キーワード ===== if ($contract_qr_id !== '') { $q->where('rc.contract_qr_id', 'like', "%{$contract_qr_id}%"); } if ($user_id !== '') { $q->where('rc.user_id', 'like', "%{$user_id}%"); } if ($user_tag_serial !== '') { $q->where('u.user_tag_serial', 'like', "%{$user_tag_serial}%"); } if ($park_id !== '') { $q->where('rc.park_id', (int) $park_id); } elseif ($selectedParkId !== '') { $q->where('rc.park_id', (int) $selectedParkId); } if ($user_phonetic !== '') { $q->where('u.user_phonetic', 'like', "%{$user_phonetic}%"); } if ($email !== '') { $q->where('u.user_primemail', 'like', "%{$email}%"); } if ($user_categoryid !== '') { $q->where('rc.user_categoryid', (int) $user_categoryid); } if ($park_name_kw !== '') { $q->where('p.park_name', 'like', "%{$park_name_kw}%"); } if ($zone_name !== '') { $q->where('z.zone_name', 'like', "%{$zone_name}%"); } if ($merge_phonetic_normalized !== null) { $likeKeyword = '%' . $merge_phonetic_normalized . '%'; $q->whereRaw("REPLACE(REPLACE(IFNULL(rc.chk_user_phonetic, ''), ' ', ''), ' ', '') LIKE ?", [$likeKeyword]); } if ($phone !== '') { $q->where(function ($w) use ($phone) { $w->where('u.user_mobile', 'like', "%{$phone}%") ->orWhere('u.user_homephone', 'like', "%{$phone}%"); }); } if ($reserve_from !== '' && ($normalized = $this->normalizeDateTimeInput($reserve_from))) { $q->where('rc.reserve_date', '>=', $normalized); } if ($reserve_to !== '' && ($normalized = $this->normalizeDateTimeInput($reserve_to, true))) { $q->where('rc.reserve_date', '<=', $normalized); } if ($receipt_delivery_from !== '' && ($normalized = $this->normalizeDateTimeInput($receipt_delivery_from))) { $q->where('rc.contract_payment_day', '>=', $normalized); } if ($receipt_delivery_to !== '' && ($normalized = $this->normalizeDateTimeInput($receipt_delivery_to, true))) { $q->where('rc.contract_payment_day', '<=', $normalized); } if ($zone_keyword !== '') { $q->where(function ($w) use ($zone_keyword) { $w->where('rc.zone_id', 'like', "%{$zone_keyword}%") ->orWhere('rc.pplace_no', 'like', "%{$zone_keyword}%") ->orWhere('rc.old_contract_id', 'like', "%{$zone_keyword}%"); }); } if ($workRecordFilter === '1') { $q->where(function ($w) { $w->whereNull('rc.contract_flag') ->orWhere('rc.contract_flag', '=', 0); }); } elseif ($workRecordFilter === '2') { $q->where('rc.contract_flag', '=', 1); } if ($created_from !== '' && ($normalized = $this->normalizeDateTimeInput($created_from))) { $q->where('rc.contract_created_at', '>=', $normalized); } if ($created_to !== '' && ($normalized = $this->normalizeDateTimeInput($created_to, true))) { $q->where('rc.contract_created_at', '<=', $normalized); } if ($updated_from !== '' && ($normalized = $this->normalizeDateTimeInput($updated_from))) { $q->where('rc.contract_updated_at', '>=', $normalized); } if ($updated_to !== '' && ($normalized = $this->normalizeDateTimeInput($updated_to, true))) { $q->where('rc.contract_updated_at', '<=', $normalized); } if ($canceled_from !== '' && ($normalized = $this->normalizeDateTimeInput($canceled_from))) { $q->where('rc.contract_cancelday', '>=', $normalized); } if ($canceled_to !== '' && ($normalized = $this->normalizeDateTimeInput($canceled_to, true))) { $q->where('rc.contract_cancelday', '<=', $normalized); } if ($contract_valid_months !== '') { $q->where('rc.enable_months', (int) $contract_valid_months); } if ($contract_flag !== '') { $q->where('rc.contract_flag', (int) $contract_flag); } if ($contract_permission !== '') { $q->where('rc.contract_permission', (int) $contract_permission); } if ($tag_qr_flag !== '') { $q->where('rc.tag_qr_flag', (int) $tag_qr_flag); } if ($updateFlagFilter === '1') { $q->where('rc.update_flag', '=', 1); } elseif ($updateFlagFilter === '2') { $q->where(function ($w) { $w->whereNull('rc.update_flag') ->orWhere('rc.update_flag', '!=', 1); }); } if ($contract_cancel_flag !== '') { $q->where('rc.contract_cancel_flag', (int) $contract_cancel_flag); } // ===== ソート(仮想列は結合側にマッピング)===== $sortable = [ 'contract_id', 'contract_qr_id', 'old_contract_id', 'zone_id', 'zone_name', 'pplace_no', 'contract_periods', 'contract_periode', 'user_id', 'user_categoryid', 'reserve_id', 'park_id', 'price_parkplaceid', 'user_securitynum', 'reserve_date', 'contract_reserve', 'contract_created_at', 'contract_updated_at', 'contract_cancelday', 'contract_reduction', 'enable_months', 'printable_date', 'billing_amount', 'contract_payment_day', 'contract_money', 'refunds', 'contract_flag', 'contract_permission', 'contract_cancel_flag', 'tag_qr_flag', 'update_flag', 'pplace_allocation_flag', 'settlement_transaction_id', 'contract_seal_issue', 'storage_company_code', 'share_storage_company_code', 'ope_id', 'park_position', 'contract_manual', 'contract_notice', 'contract_payment_number', 'user_name', 'user_phonetic', 'user_mobile', 'user_homephone', 'user_primemail', 'user_regident_zip', 'usertype_name', 'park_name', ]; if (!in_array($sort, $sortable, true)) { $sort = 'contract_id'; } $sortMap = [ 'user_name' => 'u.user_name', 'user_phonetic' => 'u.user_phonetic', 'user_mobile' => 'u.user_mobile', 'user_homephone' => 'u.user_homephone', 'user_primemail' => 'u.user_primemail', 'user_regident_zip' => 'u.user_regident_zip', 'usertype_name' => 't.print_name', 'park_name' => 'p.park_name', 'zone_name' => 'z.zone_name', ]; $sortColumn = $sortMap[$sort] ?? ('rc.' . $sort); $list = $q->orderBy($sortColumn, $sortType)->paginate(50)->withQueryString(); // ===== 画面へ(Blade 側が参照するすべての変数を渡す)===== return view('admin.regularcontracts.list', [ 'list' => $list, 'sort' => $sort, 'sort_type' => $sortType, // 入力保持(テキスト) 'contract_qr_id' => $contract_qr_id, 'user_id' => $user_id, 'user_tag_serial' => $user_tag_serial, 'park_id' => $selectedParkId !== '' ? $selectedParkId : $park_id, 'user_phonetic' => $user_phonetic, 'phone' => $phone, 'email' => $email, 'user_categoryid' => $user_categoryid, 'park_name' => $park_name_kw, 'zone_keyword' => $zone_keyword, 'zone_name' => $zone_name, 'merge_phonetic' => $merge_phonetic, 'has_address' => $has_address, 'work_record' => $workRecordFilter, // 入力保持(日付) 'reserve_date_from' => $reserve_from, 'reserve_date_to' => $reserve_to, 'contract_created_from' => $created_from, 'contract_created_to' => $created_to, 'contract_updated_from' => $updated_from, 'contract_updated_to' => $updated_to, 'contract_canceled_from' => $canceled_from, 'contract_canceled_to' => $canceled_to, 'receipt_delivery_from' => $receipt_delivery_from, 'receipt_delivery_to' => $receipt_delivery_to, 'contract_valid_months' => $contract_valid_months, // 入力保持(列挙) 'contract_flag' => $contract_flag, 'contract_permission' => $contract_permission, 'tag_qr_flag' => $tag_qr_flag, 'update_flag' => $updateFlagFilter, 'contract_cancel_flag' => $contract_cancel_flag, 'userTypeOptions' => $this->buildUsertypeOptions(), 'parkOptions' => $this->buildParkOptions(), ]); } /** * 定期契約編集(GET: 画面表示 / POST: 更新実行) * - 主キー: contract_id */ public function edit(Request $request, $id) { $id = (int) $id; if ($request->isMethod('get')) { $row = DB::table('regular_contract')->where('contract_id', $id)->first(); if (!$row) { abort(404); } return view('admin.regularcontracts.edit', [ 'row' => $row, 'contract_id' => $id, ]); } $v = Validator::make($request->all(), [ 'user_id' => ['required', 'integer'], 'park_id' => ['required', 'integer'], // 任意項目 'contract_qr_id' => ['nullable', 'string', 'max:255'], 'user_categoryid' => ['nullable', 'integer'], 'reserve_id' => ['nullable', 'integer'], 'price_parkplaceid' => ['nullable', 'integer'], 'user_securitynum' => ['nullable', 'string', 'max:255'], 'reserve_date' => ['nullable', 'date'], 'contract_reserve' => ['nullable', 'string', 'max:255'], 'contract_created_at' => ['nullable', 'date'], 'contract_updated_at' => ['nullable', 'date'], 'contract_cancelday' => ['nullable', 'date'], 'contract_flag' => ['nullable', 'integer'], 'contract_permission' => ['nullable', 'integer'], 'contract_cancel_flag' => ['nullable', 'integer'], 'tag_qr_flag' => ['nullable', 'integer'], 'park_position' => ['nullable', 'string', 'max:255'], 'ope_id' => ['nullable', 'integer'], ]); if ($v->fails()) { return back()->withErrors($v)->withInput(); } $data = [ 'contract_qr_id' => $request->input('contract_qr_id'), 'user_id' => (int) $request->input('user_id'), 'user_categoryid' => $request->input('user_categoryid'), 'reserve_id' => $request->input('reserve_id'), 'park_id' => (int) $request->input('park_id'), 'price_parkplaceid' => $request->input('price_parkplaceid'), 'user_securitynum' => $request->input('user_securitynum'), 'reserve_date' => $request->input('reserve_date'), 'contract_reserve' => $request->input('contract_reserve'), 'contract_created_at' => $request->input('contract_created_at'), 'contract_updated_at' => $request->input('contract_updated_at'), 'contract_cancelday' => $request->input('contract_cancelday'), 'contract_flag' => $request->input('contract_flag'), 'contract_permission' => $request->input('contract_permission'), 'contract_cancel_flag' => $request->input('contract_cancel_flag'), 'tag_qr_flag' => $request->input('tag_qr_flag'), 'park_position' => $request->input('park_position'), 'ope_id' => $request->input('ope_id'), 'updated_at' => now(), ]; DB::table('regular_contract')->where('contract_id', $id)->update($data); return redirect()->route('regularcontracts')->with('success', '定期契約を更新しました。'); } /** * 定期契約削除 * - 物理削除(必要なら cancel フラグ運用に切替) */ public function delete(Request $request) { $ids = $request->input('ids', []); if (!is_array($ids)) { $ids = [$ids]; } $ids = array_values(array_filter( array_map('intval', $ids), static fn (int $v) => $v > 0 )); if (empty($ids)) { return redirect()->route('regularcontracts') ->with('error', '削除する定期契約が選択されていません。'); } DB::table('regular_contract') ->whereIn('contract_id', $ids) ->delete(); return redirect()->route('regularcontracts')->with('success', '定期契約を削除しました。'); } /** * 定期契約インポート(仮実装) */ public function import(Request $request) { if ($request->isMethod('get')) { // GET で来たら一覧へ return redirect()->route('regularcontracts'); } // ファイル必須 & 形式チェック $request->validate([ 'file' => ['required', 'file', 'mimetypes:text/plain,text/csv,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'], ], [], [ 'file' => 'インポートファイル', ]); $file = $request->file('file'); // TODO: ここで実際のインポート処理(CSV/XLSXの解析とレコード登録)を書く // 例:Storage::putFile('imports', $file); で一旦保存してバッチに回す etc. return redirect()->route('regularcontracts')->with('success', 'インポートを受け付けました。'); } /** * 定期契約エクスポート(仮実装) * - 現時点では何もしません。ルーティング確認用のプレーンテキストを返します。 * - 後で CSV / Excel 出力処理に置き換えてください。 */ public function export(Request $request) { $params = $request->all(); $sort = $params['sort'] ?? 'contract_id'; $sortType = strtolower($params['sort_type'] ?? 'asc') === 'desc' ? 'desc' : 'asc'; $type = (string) ($request->query('type') ?? ''); $fileName = match ($type) { 'smbc' => '定期契約マスタ_SMBC.csv', 'city' => '定期契約マスタ_役所提出用.csv', default => '定期契約マスタ.csv', }; $query = $this->buildListQuery($params); $columns = [ 'contract_id' => '契約ID', 'contract_qr_id' => '定期契約ID', 'old_contract_id' => '旧定期契約番号', 'pplace_no' => '車室番号', 'user_id' => '利用者ID', 'user_categoryid' => '利用者分類ID', 'tag_qr_flag' => 'タグ・QR', 'park_id' => '駐輪場ID', 'reserve_date' => '予約日時', 'contract_periods' => '有効期間S', 'contract_periode' => '有効期間E', 'price_parkplaceid' => '駐輪場所ID', 'user_securitynum' => '防犯登録番号', 'contract_created_at' => '契約日時', 'contract_updated_at' => '更新可能日', 'contract_cancelday' => '解約日時', 'contract_reduction' => '減免措置', 'enable_months' => '定期有効月数', 'printable_date' => 'シール印刷可能日', 'billing_amount' => '請求金額', 'pplace_allocation_flag' => '車室割り当てフラグ', 'contract_payment_day' => '授受日時', 'contract_money' => '授受金額', 'contract_flag' => '授受フラグ', 'settlement_transaction_id' => '決済トランザクションID', 'contract_seal_issue' => 'シール発行数', 'storage_company_code' => '収納企業コード', 'share_storage_company_code' => '共有先収納企業コード', 'accept_number' => '受付番号', 'update_flag' => '(更新元)契約更新済フラグ', 'vehicle_type_id' => '車種区分ID', 'chk_user_phonetic' => 'チェック用_フリガナ', 'user_regident_zip' => 'チェック用_居住所郵便番号', 'user_mobile' => 'チェック用_携帯電話番号', 'user_homephone' => 'チェック用_自宅電話番号', 'old_member_number' => 'チェック用_旧会員番号', 'user_name' => '利用者氏名', 'user_phonetic' => '利用者フリガナ', 'park_name' => '駐輪場名', 'zone_name' => 'ゾーン名', 'usertype_name' => '利用者分類名', ]; $dateColumns = [ 'contract_periods', 'contract_periode', 'contract_created_at', 'contract_updated_at', 'contract_cancelday', 'printable_date', 'contract_payment_day', 'reserve_date', ]; $rows = $query->orderBy($sort, $sortType)->get(); $headers = [ 'Content-Type' => 'text/csv; charset=Shift_JIS', 'Content-Disposition' => "attachment; filename=\"{$fileName}\"", ]; return response()->streamDownload(function () use ($rows, $columns, $dateColumns) { $handle = fopen('php://output', 'w'); $headerRow = array_map(fn ($label) => mb_convert_encoding($label, 'SJIS-win', 'UTF-8'), array_values($columns)); fputcsv($handle, $headerRow); foreach ($rows as $row) { $line = []; foreach ($columns as $key => $label) { $value = $row->{$key} ?? ''; if (in_array($key, $dateColumns, true) && $value) { try { $value = \Illuminate\Support\Carbon::parse($value)->format(str_contains($key, '_day') || str_contains($key, '_date') ? 'Y-m-d H:i' : 'Y-m-d'); } catch (\Throwable $e) { $value = (string) $value; } } elseif ($key === 'tag_qr_flag' && $value !== '') { $value = ((int) $value) === 1 ? 'QR' : 'タグ'; } elseif ($key === 'pplace_allocation_flag' && $value !== '') { $value = ((int) $value) === 1 ? '割当済' : '未割当'; } elseif ($key === 'contract_flag' && $value !== '') { $value = ((int) $value) === 1 ? '済' : '未'; } elseif ($key === 'update_flag' && $value !== '') { $value = ((int) $value) === 1 ? '更新済' : '未更新'; } $line[] = mb_convert_encoding((string) $value, 'SJIS-win', 'UTF-8'); } fputcsv($handle, $line); } fclose($handle); }, $fileName, $headers); } // 追加:新規登録(GET: 画面表示 / POST: 登録実行) public function add(Request $request) { // 画面表示 if ($request->isMethod('get')) { return view('admin.regularcontracts.add'); } // ========= バリデーション ========= // ※ 必須最小限。その他は任意(nullable) $v = Validator::make( $request->all(), [ 'user_id' => ['required', 'integer'], 'park_id' => ['required', 'integer'], 'contract_qr_id' => ['nullable', 'string', 'max:255'], 'user_categoryid' => ['nullable', 'integer'], 'reserve_id' => ['nullable', 'integer'], 'price_parkplaceid' => ['nullable', 'integer'], 'reserve_date' => ['nullable', 'date'], 'contract_created_at' => ['nullable', 'date'], 'contract_cancelday' => ['nullable', 'date'], 'contract_permission' => ['nullable', 'integer'], 'contract_cancel_flag' => ['nullable', 'integer'], 'tag_qr_flag' => ['nullable', 'integer'], 'update_flag' => ['nullable', 'integer'], 'park_position' => ['nullable', 'string', 'max:255'], 'ope_id' => ['nullable', 'integer'], // 画面の「定期有効月数」は DB の contract_valid_months に保存する 'enable_months' => ['nullable', 'integer', 'min:0'], ], [], [ 'user_id' => '利用者ID', 'park_id' => '駐輪場ID', 'contract_qr_id' => '定期契約QRID', 'user_categoryid' => '利用者分類ID', 'reserve_id' => '定期予約ID', 'price_parkplaceid' => '駐輪場所ID', 'reserve_date' => '予約日時', 'contract_created_at' => '契約日時', 'contract_cancelday' => '解約日時', 'contract_permission' => 'シール発行許可', 'contract_cancel_flag' => '解約フラグ', 'tag_qr_flag' => 'タグ・QR', 'update_flag' => '(更新元)契約更新済フラグ', 'park_position' => '駐輪位置番号', 'ope_id' => 'オペレータID', 'enable_months' => '定期有効月数', ] ); if ($v->fails()) { return back()->withErrors($v)->withInput(); } // ========= 登録データ作成 ========= // ここでは「regular_contract」テーブルに確実にある列を中心に保存します。 // 追加したい列があれば、同様にキーを増やして下さい。 $data = [ 'contract_qr_id' => $request->input('contract_qr_id'), 'user_id' => (int) $request->input('user_id'), 'user_categoryid' => $request->input('user_categoryid'), 'reserve_id' => $request->input('reserve_id'), 'park_id' => (int) $request->input('park_id'), 'price_parkplaceid' => $request->input('price_parkplaceid'), 'reserve_date' => $request->input('reserve_date'), 'contract_created_at' => $request->input('contract_created_at') ?: now(), // 未指定なら現在時刻 'contract_cancelday' => $request->input('contract_cancelday'), 'contract_permission' => $request->input('contract_permission'), 'contract_cancel_flag' => $request->input('contract_cancel_flag'), 'tag_qr_flag' => $request->input('tag_qr_flag'), 'update_flag' => $request->input('update_flag'), 'park_position' => $request->input('park_position'), 'ope_id' => $request->input('ope_id'), // 画面の enable_months → DB の contract_valid_months 'contract_valid_months' => $request->input('enable_months'), 'created_at' => now(), 'updated_at' => now(), ]; DB::table('regular_contract')->insert($data); return redirect() ->route('regularcontracts') ->with('success', '定期契約を登録しました。'); } private function buildListQuery(array $params) { $contract_qr_id = trim((string)($params['contract_qr_id'] ?? '')); $user_id = trim((string)($params['user_id'] ?? '')); $user_tag_serial = trim((string)($params['user_tag_serial'] ?? '')); $park_id = trim((string)($params['park_id'] ?? '')); $selectedParkId = trim((string)($params['selected_park_id'] ?? '')); $user_phonetic = trim((string)($params['user_phonetic'] ?? '')); $phone = trim((string)($params['phone'] ?? '')); $email = trim((string)($params['email'] ?? '')); $user_categoryid = trim((string)($params['user_categoryid'] ?? '')); $park_name_kw = trim((string)($params['park_name'] ?? '')); $zone_keyword = trim((string)($params['zone_keyword'] ?? '')); $zone_name = trim((string)($params['zone_name'] ?? '')); $merge_phonetic_input = $params['merge_phonetic'] ?? ''; $merge_phonetic = trim((string)$merge_phonetic_input); $merge_phonetic_normalized = $this->normalizePhoneticKeyword($merge_phonetic); $workRecordFilter = (string)($params['work_record'] ?? '0'); if (!in_array($workRecordFilter, ['0', '1', '2'], true)) { $workRecordFilter = '0'; } $reserve_from = $params['reserve_date_from'] ?? ''; $reserve_to = $params['reserve_date_to'] ?? ''; $created_from = $params['contract_created_from'] ?? ''; $created_to = $params['contract_created_to'] ?? ''; $updated_from = $params['contract_updated_from'] ?? ''; $updated_to = $params['contract_updated_to'] ?? ''; $canceled_from = $params['contract_canceled_from'] ?? ''; $canceled_to = $params['contract_canceled_to'] ?? ''; $receipt_delivery_from = $params['receipt_delivery_from'] ?? ''; $receipt_delivery_to = $params['receipt_delivery_to'] ?? ''; $contract_valid_months = $params['contract_valid_months'] ?? ''; $contract_flag = $params['contract_flag'] ?? ''; $contract_permission = $params['contract_permission'] ?? ''; $tag_qr_flag = $params['tag_qr_flag'] ?? ''; $updateFlagFilter = (string)($params['update_flag'] ?? '0'); if (!in_array($updateFlagFilter, ['0', '1', '2'], true)) { $updateFlagFilter = '0'; } $contract_cancel_flag = $params['contract_cancel_flag'] ?? ''; $q = DB::table('regular_contract as rc') ->leftJoin('user as u', 'u.user_id', '=', 'rc.user_id') ->leftJoin('usertype as t', 't.user_categoryid', '=', 'rc.user_categoryid') ->leftJoin('park as p', 'p.park_id', '=', 'rc.park_id') ->leftJoin('zone as z', 'z.zone_id', '=', 'rc.zone_id') ->select([ 'rc.*', 'u.user_seq', 'u.user_name', 'u.user_phonetic', 'u.user_mobile', 'u.user_homephone', 'u.user_primemail', 'u.user_regident_zip', 'u.user_tag_serial', DB::raw('t.print_name as usertype_name'), 't.usertype_subject1', 't.usertype_subject2', 't.usertype_subject3', DB::raw('p.park_name as park_name'), DB::raw('z.zone_name as zone_name'), ]); if ($contract_qr_id !== '') { $q->where('rc.contract_qr_id', 'like', "%{$contract_qr_id}%"); } if ($user_id !== '') { $q->where('rc.user_id', 'like', "%{$user_id}%"); } if ($user_tag_serial !== '') { $q->where('u.user_tag_serial', 'like', "%{$user_tag_serial}%"); } if ($park_id !== '') { $q->where('rc.park_id', (int)$park_id); } elseif ($selectedParkId !== '') { $q->where('rc.park_id', (int)$selectedParkId); } if ($user_phonetic !== '') { $q->where('u.user_phonetic', 'like', "%{$user_phonetic}%"); } if ($email !== '') { $q->where('u.user_primemail', 'like', "%{$email}%"); } if ($user_categoryid !== '') { $q->where('rc.user_categoryid', (int)$user_categoryid); } if ($park_name_kw !== '') { $q->where('p.park_name', 'like', "%{$park_name_kw}%"); } if ($zone_name !== '') { $q->where('z.zone_name', 'like', "%{$zone_name}%"); } if ($merge_phonetic_normalized !== null) { $likeKeyword = '%' . $merge_phonetic_normalized . '%'; $q->whereRaw("REPLACE(REPLACE(IFNULL(rc.chk_user_phonetic, ''), ' ', ''), ' ', '') LIKE ?", [$likeKeyword]); } if ($phone !== '') { $q->where(function ($w) use ($phone) { $w->where('u.user_mobile', 'like', "%{$phone}%") ->orWhere('u.user_homephone', 'like', "%{$phone}%"); }); } if ($reserve_from !== '' && ($normalized = $this->normalizeDateTimeInput($reserve_from))) { $q->where('rc.reserve_date', '>=', $normalized); } if ($reserve_to !== '' && ($normalized = $this->normalizeDateTimeInput($reserve_to, true))) { $q->where('rc.reserve_date', '<=', $normalized); } if ($receipt_delivery_from !== '' && ($normalized = $this->normalizeDateTimeInput($receipt_delivery_from))) { $q->where('rc.contract_payment_day', '>=', $normalized); } if ($receipt_delivery_to !== '' && ($normalized = $this->normalizeDateTimeInput($receipt_delivery_to, true))) { $q->where('rc.contract_payment_day', '<=', $normalized); } if ($zone_keyword !== '') { $q->where(function ($w) use ($zone_keyword) { $w->where('rc.zone_id', 'like', "%{$zone_keyword}%") ->orWhere('rc.pplace_no', 'like', "%{$zone_keyword}%") ->orWhere('rc.old_contract_id', 'like', "%{$zone_keyword}%"); }); } if ($workRecordFilter === '1') { $q->where(function ($w) { $w->whereNull('rc.contract_flag') ->orWhere('rc.contract_flag', '=', 0); }); } elseif ($workRecordFilter === '2') { $q->where('rc.contract_flag', '=', 1); } if ($created_from !== '' && ($normalized = $this->normalizeDateTimeInput($created_from))) { $q->where('rc.contract_created_at', '>=', $normalized); } if ($created_to !== '' && ($normalized = $this->normalizeDateTimeInput($created_to, true))) { $q->where('rc.contract_created_at', '<=', $normalized); } if ($updated_from !== '' && ($normalized = $this->normalizeDateTimeInput($updated_from))) { $q->where('rc.contract_updated_at', '>=', $normalized); } if ($updated_to !== '' && ($normalized = $this->normalizeDateTimeInput($updated_to, true))) { $q->where('rc.contract_updated_at', '<=', $normalized); } if ($canceled_from !== '' && ($normalized = $this->normalizeDateTimeInput($canceled_from))) { $q->where('rc.contract_cancelday', '>=', $normalized); } if ($canceled_to !== '' && ($normalized = $this->normalizeDateTimeInput($canceled_to, true))) { $q->where('rc.contract_cancelday', '<=', $normalized); } if ($contract_valid_months !== '') { $q->where('rc.enable_months', (int)$contract_valid_months); } if ($contract_flag !== '') { $q->where('rc.contract_flag', (int)$contract_flag); } if ($contract_permission !== '') { $q->where('rc.contract_permission', (int)$contract_permission); } if ($tag_qr_flag !== '') { $q->where('rc.tag_qr_flag', (int)$tag_qr_flag); } if ($updateFlagFilter === '1') { $q->where('rc.update_flag', '=', 1); } elseif ($updateFlagFilter === '2') { $q->where(function ($w) { $w->whereNull('rc.update_flag') ->orWhere('rc.update_flag', '!=', 1); }); } if ($contract_cancel_flag !== '') { $q->where('rc.contract_cancel_flag', (int)$contract_cancel_flag); } return $q; } }