diff --git a/app/Http/Controllers/Admin/RegularContractController.php b/app/Http/Controllers/Admin/RegularContractController.php index 17a5a55..0b2250f 100644 --- a/app/Http/Controllers/Admin/RegularContractController.php +++ b/app/Http/Controllers/Admin/RegularContractController.php @@ -5,9 +5,91 @@ namespace App\Http\Controllers\Admin; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Validator; +use App\Models\Park; +use Illuminate\Support\Carbon; class RegularContractController { + /** + * 利用者分類選択肢(user_categoryid 昇順) + */ + private function buildUsertypeOptions(): array + { + return DB::table('usertype as t') + ->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) @@ -16,74 +98,86 @@ class RegularContractController */ public function list(Request $request) { - // ===== ソート(既定: contract_id DESC)===== - $sort = $request->input('sort', 'contract_id'); - $sortType = strtolower($request->input('sort_type', 'desc')) === 'asc' ? 'asc' : 'desc'; + 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'; // ===== 絞り込み(テキスト系)===== - // フォームの name 属性と完全一致させる&既定値は空文字にして Blade が未定義にならないようにする - $contract_qr_id = trim((string) $request->input('contract_qr_id', '')); - $user_id = trim((string) $request->input('user_id', '')); - $park_id = trim((string) $request->input('park_id', '')); - $user_phonetic = trim((string) $request->input('user_phonetic', '')); // フリガナ - $phone = trim((string) $request->input('phone', '')); // 電話(携帯/自宅) - $email = trim((string) $request->input('email', '')); // メール - $usertype_name_kw = trim((string) $request->input('usertype_name', '')); // 利用者分類名 - $park_name_kw = trim((string) $request->input('park_name', '')); // 駐輪場名 + $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 = $request->input('reserve_date_from', ''); - $reserve_to = $request->input('reserve_date_to', ''); - $created_from = $request->input('contract_created_from', ''); - $created_to = $request->input('contract_created_to', ''); - $updated_from = $request->input('contract_updated_from', ''); - $updated_to = $request->input('contract_updated_to', ''); - $canceled_from = $request->input('contract_canceled_from', ''); - $canceled_to = $request->input('contract_canceled_to', ''); + $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 = $request->input('contract_flag', ''); - $contract_permission = $request->input('contract_permission', ''); - $tag_qr_flag = $request->input('tag_qr_flag', ''); - $update_flag = $request->input('update_flag', ''); - $contract_cancel_flag = $request->input('contract_cancel_flag', ''); + $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 - 'rc.contract_id', - 'rc.contract_qr_id', - 'rc.user_id', - 'rc.user_categoryid', - 'rc.reserve_id', - 'rc.park_id', - 'rc.price_parkplaceid', - 'rc.user_securitynum', - 'rc.reserve_date', - 'rc.contract_reserve', - 'rc.contract_created_at', - 'rc.contract_updated_at', - 'rc.contract_cancelday', - 'rc.contract_flag', - 'rc.contract_permission', - 'rc.contract_cancel_flag', - 'rc.tag_qr_flag', - 'rc.update_flag', - 'rc.park_position', - 'rc.ope_id', - // user + 'rc.*', + 'u.user_seq', 'u.user_name', 'u.user_phonetic', 'u.user_mobile', 'u.user_homephone', 'u.user_primemail', - // usertype & park + '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 / キーワード ===== @@ -93,8 +187,13 @@ class RegularContractController 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', 'like', "%{$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}%"); @@ -102,46 +201,73 @@ class RegularContractController if ($email !== '') { $q->where('u.user_primemail', 'like', "%{$email}%"); } - if ($usertype_name_kw !== '') { - $q->where('t.print_name', 'like', "%{$usertype_name_kw}%"); + 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) { - $q->whereDate('rc.reserve_date', '>=', $reserve_from); + if ($reserve_from !== '' && ($normalized = $this->normalizeDateTimeInput($reserve_from))) { + $q->where('rc.reserve_date', '>=', $normalized); } - if ($reserve_to) { - $q->whereDate('rc.reserve_date', '<=', $reserve_to); + if ($reserve_to !== '' && ($normalized = $this->normalizeDateTimeInput($reserve_to, true))) { + $q->where('rc.reserve_date', '<=', $normalized); } - if ($created_from) { - $q->whereDate('rc.contract_created_at', '>=', $created_from); + if ($receipt_delivery_from !== '' && ($normalized = $this->normalizeDateTimeInput($receipt_delivery_from))) { + $q->where('rc.contract_payment_day', '>=', $normalized); } - if ($created_to) { - $q->whereDate('rc.contract_created_at', '<=', $created_to); + if ($receipt_delivery_to !== '' && ($normalized = $this->normalizeDateTimeInput($receipt_delivery_to, true))) { + $q->where('rc.contract_payment_day', '<=', $normalized); } - if ($updated_from) { - $q->whereDate('rc.contract_updated_at', '>=', $updated_from); + 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 ($updated_to) { - $q->whereDate('rc.contract_updated_at', '<=', $updated_to); + 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 ($canceled_from) { - $q->whereDate('rc.contract_cancelday', '>=', $canceled_from); + if ($created_from !== '' && ($normalized = $this->normalizeDateTimeInput($created_from))) { + $q->where('rc.contract_created_at', '>=', $normalized); } - if ($canceled_to) { - $q->whereDate('rc.contract_cancelday', '<=', $canceled_to); + 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); } @@ -151,8 +277,13 @@ class RegularContractController if ($tag_qr_flag !== '') { $q->where('rc.tag_qr_flag', (int) $tag_qr_flag); } - if ($update_flag !== '') { - $q->where('rc.update_flag', (int) $update_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); @@ -160,34 +291,16 @@ class RegularContractController // ===== ソート(仮想列は結合側にマッピング)===== $sortable = [ - 'contract_id', - 'contract_qr_id', - '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_flag', - 'contract_permission', - 'contract_cancel_flag', - 'tag_qr_flag', - 'update_flag', - 'park_position', - 'ope_id', - // 結合先の見出し列 - 'user_name', - 'user_phonetic', - 'user_mobile', - 'user_homephone', - 'user_primemail', - 'usertype_name', - 'park_name', + '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'; @@ -198,12 +311,14 @@ class RegularContractController '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); + $list = $q->orderBy($sortColumn, $sortType)->paginate(50)->withQueryString(); // ===== 画面へ(Blade 側が参照するすべての変数を渡す)===== return view('admin.regularcontracts.list', [ @@ -214,12 +329,18 @@ class RegularContractController // 入力保持(テキスト) 'contract_qr_id' => $contract_qr_id, 'user_id' => $user_id, - 'park_id' => $park_id, + 'user_tag_serial' => $user_tag_serial, + 'park_id' => $selectedParkId !== '' ? $selectedParkId : $park_id, 'user_phonetic' => $user_phonetic, 'phone' => $phone, 'email' => $email, - 'usertype_name' => $usertype_name_kw, + '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, @@ -230,13 +351,19 @@ class RegularContractController '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' => $update_flag, + 'update_flag' => $updateFlagFilter, 'contract_cancel_flag' => $contract_cancel_flag, + + 'userTypeOptions' => $this->buildUsertypeOptions(), + 'parkOptions' => $this->buildParkOptions(), ]); } @@ -318,15 +445,23 @@ class RegularContractController */ public function delete(Request $request) { - $id = (int) $request->input('id'); - DB::table('regular_contract')->where('contract_id', $id)->delete(); + $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 + )); - // 例:論理削除運用にする場合(必要なら運用側で切替) - // DB::table('regular_contract')->where('contract_id', $id)->update([ - // 'contract_cancel_flag' => 1, - // 'contract_cancelday' => now(), - // 'updated_at' => now(), - // ]); + if (empty($ids)) { + return redirect()->route('regularcontracts') + ->with('error', '削除する定期契約が選択されていません。'); + } + + DB::table('regular_contract') + ->whereIn('contract_id', $ids) + ->delete(); return redirect()->route('regularcontracts')->with('success', '定期契約を削除しました。'); } @@ -366,70 +501,115 @@ class RegularContractController public function export(Request $request) { - // ── 出力タイプ(通常 / SMBC / 役所) ────────────────────────────── - $type = $request->query('type'); // null | smbc | city + $params = $request->all(); + $sort = $params['sort'] ?? 'contract_id'; + $sortType = strtolower($params['sort_type'] ?? 'asc') === 'desc' ? 'desc' : 'asc'; + $type = (string) ($request->query('type') ?? ''); - // ── 出力ファイル名 ─────────────────────────────────────────────── - $downloadName = '定期契約マスタ.csv'; - if ($type === 'smbc') - $downloadName = '定期契約マスタ_SMBC.csv'; - if ($type === 'city') - $downloadName = '定期契約マスタ_役所提出用.csv'; + $fileName = match ($type) { + 'smbc' => '定期契約マスタ_SMBC.csv', + 'city' => '定期契約マスタ_役所提出用.csv', + default => '定期契約マスタ.csv', + }; - // ── 生成先(storage/app/tmp 配下の一時ファイル) ───────────────── - $tmpDir = storage_path('app/tmp'); - if (!is_dir($tmpDir)) { - @mkdir($tmpDir, 0755, true); - } - $tmpPath = $tmpDir . '/' . uniqid('regularcontracts_', true) . '.csv'; + $query = $this->buildListQuery($params); - // ── CSV を作成(Excel を考慮し UTF-8 BOM を付与) ─────────────── - $fp = fopen($tmpPath, 'w+'); - if ($fp === false) { - abort(500, 'CSV一時ファイルを作成できませんでした。'); - } - // Excel 対策:BOM - fwrite($fp, "\xEF\xBB\xBF"); + $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' => '利用者分類名', + ]; - // ヘッダー行(必要に応じて列を増減) - fputcsv($fp, ['定期契約ID', '利用者ID', '駐輪場ID', '契約日時']); + $dateColumns = [ + 'contract_periods', + 'contract_periode', + 'contract_created_at', + 'contract_updated_at', + 'contract_cancelday', + 'printable_date', + 'contract_payment_day', + 'reserve_date', + ]; - // ── データ取得(大量件数に備え chunk で分割取得) ──────────────── - // ※ list() と同等の JOIN/SELECT を最低限に簡略化 - DB::table('regular_contract as rc') - ->leftJoin('user as u', 'u.user_id', '=', 'rc.user_id') - ->orderBy('rc.contract_id', 'asc') - ->select([ - 'rc.contract_qr_id', - 'rc.user_id', - 'rc.park_id', - 'rc.contract_created_at', - ]) - ->chunk(1000, function ($rows) use ($fp) { - foreach ($rows as $r) { - fputcsv($fp, [ - $r->contract_qr_id, - $r->user_id, - $r->park_id, - $r->contract_created_at, - ]); + $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($fp); - - // ── ダウンロードレスポンス(送信後に一時ファイル削除) ──────────── - return response()->download( - $tmpPath, - $downloadName, - [ - 'Content-Type' => 'text/csv; charset=UTF-8', - 'Content-Disposition' => 'attachment; filename="' . $downloadName . '"', - 'Pragma' => 'no-cache', - 'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0', - 'Expires' => '0', - ] - )->deleteFileAfterSend(true); + fclose($handle); + }, $fileName, $headers); } @@ -523,6 +703,178 @@ class RegularContractController ->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; + } } diff --git a/resources/js/app.js b/resources/js/app.js index d409034..6037c80 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -1,25 +1,16 @@ -/** - * First we will load all of this project's JavaScript dependencies which - * includes Vue and other libraries. It is a great starting point when - * building robust, powerful web applications using Vue and Laravel. - */ - // require('./bootstrap'); require('jquery-confirm/js/jquery-confirm'); // window.Vue = require('vue'); -/** - * Next, we will create a fresh Vue application instance and attach it to - * the page. Then, you may begin adding components to this application - * or customize the JavaScript scaffolding to fit your unique needs. - */ - //Vue.component('example-component', require('./components/ExampleComponent.vue')); // const app = new Vue({ // el: '#app' // }); +/** + * チェックボックス全選・解除 + */ $('#checkbox_all').on('ifChecked ifUnchecked', function (event) { if (event.type == 'ifChecked') { $('input.checkbox:not(:disabled)').iCheck('check'); @@ -28,8 +19,10 @@ $('#checkbox_all').on('ifChecked ifUnchecked', function (event) { } }); +/** + * 削除ボタン押下時の確認ダイアログ + */ $('#delete').on('click', function () { - $.confirm({ title: '確認ダイアログ。', content: '!※※※このレコードは他のテーブルから参照されている可能性があります。削除の際は十分注意してください。\n' + @@ -43,11 +36,14 @@ $('#delete').on('click', function () { $("#form_delete").submit(); } }, - いいえ: function () { - } + いいえ: function () {} } }); }); + +/** + * CSVインポート確認ダイアログ + */ $('#import_csv').on('click', function () { var action = $(this).attr('action'), token = $('meta[name="csrf-token"]').attr('content'); @@ -55,10 +51,10 @@ $('#import_csv').on('click', function () { title: 'インポート確認ダイアログ。', content: '' + '
' + - '' + + '' + '

!データをインポートします。既存のデータは全て削除します。継続してよろしいですか? はい/いいえ。

' + '
' + - '' + + '' + '
' + '
', buttons: { @@ -69,13 +65,14 @@ $('#import_csv').on('click', function () { $("#form_import").submit(); } }, - いいえ: function () { - //close - }, + いいえ: function () {} } }); }); +/** + * CSV出力確認ダイアログ + */ $('#export_csv').on('click', function () { var action = $(this).attr('action'), user_id = $('#user_id').val(), @@ -107,41 +104,70 @@ $('#export_csv').on('click', function () { '&isExport=1'; } }, - いいえ: function () { - } + いいえ: function () {} } }); - - }); +/** + * ソート処理(▲▼アイコン付き) + */ +$(document).on('click', '.rc-table thead th.sorting, .rc-table thead th.sorting_asc, .rc-table thead th.sorting_desc', function (e) { + e.preventDefault(); -// for sorting -$('.table thead th.sorting').on('click', function (e) { - var sort = $(this).attr('sort'); - var sort_type = 'asc'; - if ($(this).hasClass('sorting_asc')) { - sort_type = 'desc' + var $header = $(this); + var form = document.getElementById('list-form'); + if (!form) { + return; } - $('input:hidden[name="sort"]').val(sort); - $('input:hidden[name="sort_type"]').val(sort_type); - $('form#list-form').submit(); + + var sortKey = $header.attr('sort'); + if (!sortKey) { + return; + } + + var wasAsc = $header.hasClass('sorting_asc'); + var sortType = wasAsc ? 'desc' : 'asc'; + + $('.rc-table thead th.sorting, .rc-table thead th.sorting_asc, .rc-table thead th.sorting_desc') + .removeClass('sorting_asc sorting_desc'); + $header.addClass(wasAsc ? 'sorting_desc' : 'sorting_asc'); + + form.querySelector('input[name="sort"]').value = sortKey; + form.querySelector('input[name="sort_type"]').value = sortType; + + var params = new URLSearchParams(new FormData(form)); + params.delete('page'); + + var action = form.getAttribute('action') || window.location.pathname; + var base = action.split('?')[0]; + var query = params.toString(); + + window.location.href = query ? base + '?' + query : base; }); +/** + * 日付ピッカー初期化 + */ $('.date').datepicker({ language: "ja", format: "yyyy/mm/dd" }); - +/** + * 利用者選択時に電話番号を自動入力 + */ $('#select_user').on('change', function () { - var mobile = $('option:selected', this).attr('mobile'), + var mobile = $('option:selected', this).attr('mobile'), homePhone = $('option:selected', this).attr('homePhone'); $('#mobile').val(mobile); $('#homephone').val(homePhone); }); $('#select_user').trigger('change'); +/** + * 登録ボタン押下時の確認 + */ $('.register').on('click', function (e) { e.preventDefault(); $.confirm({ @@ -156,13 +182,14 @@ $('.register').on('click', function (e) { $("form").submit(); } }, - いいえ: function () { - } + いいえ: function () {} } }); }); -// 編集画面専用 登録ボタン +/** + * 編集画面:登録処理 + */ $('#register_edit').on('click', function (e) { e.preventDefault(); $.confirm({ @@ -173,7 +200,7 @@ $('#register_edit').on('click', function (e) { text: "はい", btnClass: 'btn-primary', action: function () { - $("#form_edit").submit(); // 更新処理 + $("#form_edit").submit(); } }, いいえ: function () {} @@ -181,7 +208,9 @@ $('#register_edit').on('click', function (e) { }); }); -// 編集画面専用 削除ボタン +/** + * 編集画面:削除処理 + */ $('#delete_edit').on('click', function (e) { e.preventDefault(); $.confirm({ @@ -192,11 +221,10 @@ $('#delete_edit').on('click', function (e) { text: "はい", btnClass: 'btn-primary', action: function () { - $("#form_delete").submit(); // 削除処理 + $("#form_delete").submit(); } }, いいえ: function () {} } }); }); - diff --git a/resources/views/admin/regularcontracts/_form.blade.php b/resources/views/admin/regularcontracts/_form.blade.php index 388c284..cf17385 100644 --- a/resources/views/admin/regularcontracts/_form.blade.php +++ b/resources/views/admin/regularcontracts/_form.blade.php @@ -17,12 +17,6 @@ @endif -
- @if($isInfo) - 登録 - 編集 - @endIf -
@@ -547,9 +541,14 @@
@if($isInfo) - 登録 - 編集 + 登録 + 編集 @else - +
+ + @if($isEdit) + + @endif +
@endIf
diff --git a/resources/views/admin/regularcontracts/add.blade.php b/resources/views/admin/regularcontracts/add.blade.php index 1cf76ce..1c73e9a 100644 --- a/resources/views/admin/regularcontracts/add.blade.php +++ b/resources/views/admin/regularcontracts/add.blade.php @@ -34,14 +34,12 @@
- {{-- 上部:登録ボタン(駐輪場所・料金マスタのトーンに合わせた薄いボタン) --}} -
- -
-
-
-
+
+ +
+
+ @csrf {{-- ====== 1段目 ====== --}} @@ -334,7 +332,7 @@ {{-- 下部:登録ボタン --}}
- + 戻る
@@ -344,4 +342,44 @@
+@push('scripts') + +@endpush @endsection diff --git a/resources/views/admin/regularcontracts/edit.blade.php b/resources/views/admin/regularcontracts/edit.blade.php index 6a696a4..5812e16 100644 --- a/resources/views/admin/regularcontracts/edit.blade.php +++ b/resources/views/admin/regularcontracts/edit.blade.php @@ -10,12 +10,6 @@ .rc-edit .breadcrumb { font-size: 13px; } - .rc-toolbar{ - display:flex;align-items:center;justify-content:space-between;gap:.75rem; - margin-top:.25rem;margin-bottom:.75rem; - } - .rc-toolbar .left .btn{margin-right:.5rem} - .card .card-header{background:#f5f5f5}
@@ -27,34 +21,27 @@
- - {{-- ← ここが “目標” のボタン帯 --}} -
-
- {{-- 登録:edit-form を submit --}} - - {{-- 領収書発行:後で好きなルートに差し替えてOK(今はダミー) --}} - -
- - {{-- 右側:削除 --}} -
- @csrf - - -
-
- {{-- /ボタン帯 --}}
+
+
+ + +
+
+ @csrf + + +
+
{{-- 本体フォーム(登録はこの form を submit) --}}
@csrf @@ -73,5 +60,32 @@ document.getElementById('btnReceipt')?.addEventListener('click', function(){ alert('領収書発行の処理をここに実装してください。'); }); + + document.addEventListener('DOMContentLoaded', function () { + $('.js-confirm-submit').on('click', function (e) { + e.preventDefault(); + const $button = $(this); + $.confirm({ + title: '確認ダイアログ。', + content: '登録してよろしいですか?はい/いいえ', + buttons: { + ok: { + text: "はい", + btnClass: 'btn-primary', + keys: ['enter'], + action: function () { + const formId = $button.attr('form'); + if (formId) { + $('#' + formId).trigger('submit'); + } else { + $button.closest('form').trigger('submit'); + } + } + }, + いいえ: function () {} + } + }); + }); + }); @endsection diff --git a/resources/views/admin/regularcontracts/list.blade.php b/resources/views/admin/regularcontracts/list.blade.php index 0b274da..fa36c66 100644 --- a/resources/views/admin/regularcontracts/list.blade.php +++ b/resources/views/admin/regularcontracts/list.blade.php @@ -90,6 +90,30 @@ .rc-page .rc-table tbody td.op-cell { background: #faebd7; } + + .rc-table thead th .sort-arrows { + display: inline-flex; + flex-direction: row; + align-items: center; + gap: 0.1rem; + margin-left: .2rem; + font-size: 12px; + line-height: 1; + font-weight: 700; + text-decoration: none; + letter-spacing: -5px; /* ↑↓を詰める */ + } + .rc-table thead th .sort-arrows .up, + .rc-table thead th .sort-arrows .down { + color: #b5b5b5; + text-decoration: none; + } + .rc-table thead th.sorting_asc .sort-arrows .up { + color: #000; + } + .rc-table thead th.sorting_desc .sort-arrows .down { + color: #000; + }
@@ -119,7 +143,7 @@

絞り込みフィルター

- + @csrf @@ -134,8 +158,16 @@
-
+
+ +
@@ -154,21 +186,23 @@
-
+
+ + + +
+ value="{{ $contract_qr_id ?? '' }}" placeholder="定期契約ID">
@@ -189,8 +223,16 @@
-
+
+ +
@@ -234,18 +276,24 @@
-
+
+ +
@@ -287,21 +335,19 @@
新規 + {{-- 3種のエクスポートは共通の確認モーダルを使い、data-url に出力先URLを渡す --}} - + - + - +
- {{ $list->appends(['sort' => $sort, 'sort_type' => $sort_type])->links('pagination') }} + {{ $list->appends(request()->except('page'))->links('pagination') }}
@@ -312,58 +358,169 @@ @csrf
+ @php + $currentSort = $sort ?? 'contract_id'; + $currentDir = strtolower($sort_type ?? 'asc'); + if (!in_array($currentDir, ['asc', 'desc'], true)) { + $currentDir = 'asc'; + } + $sortClass = function (string $key) use ($currentSort, $currentDir) { + $base = 'sorting'; + if ($currentSort === $key) { + return $base . ' ' . ($currentDir === 'asc' ? 'sorting_asc' : 'sorting_desc'); + } + return $base; + }; + @endphp + @php + $renderSortIcon = static function (string $key) { + return ''; + }; + @endphp - @php $next = ($sort === 'contract_id' && $sort_type === 'asc') ? 'desc' : 'asc'; @endphp - + {{-- 操作列(チェック+編集。背景色を付与) --}} + - {{-- 操作列(チェック+編集。背景色を付与) --}} - - {{-- 表頭(要件に合わせて網羅) --}} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @php + $formatYmd = static function ($value) { + if (empty($value)) { + return ''; + } + try { + return \Illuminate\Support\Carbon::parse($value)->format('Y-m-d'); + } catch (\Throwable $e) { + return mb_substr((string) $value, 0, 10); + } + }; + $formatYmdHi = static function ($value) { + if (empty($value)) { + return ''; + } + try { + return \Illuminate\Support\Carbon::parse($value)->format('Y-m-d H:i'); + } catch (\Throwable $e) { + return mb_substr((string) $value, 0, 16); + } + }; + @endphp @foreach($list as $item) {{-- 先頭の並び替え列(行の contract_id を表示) --}} @@ -372,7 +529,7 @@ {{-- 操作列:チェック + 編集(背景色つき) --}} - - - - - + + + + @php + $userCategoryLabel = collect([ + $item->usertype_subject1 ?? '', + $item->usertype_subject2 ?? '', + $item->usertype_subject3 ?? '', + ])->filter(fn ($v) => $v !== '')->implode('/'); + @endphp + - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - + + + + + + + + - + @@ -424,11 +595,6 @@
- + + 契約ID {!! $renderSortIcon('contract_id') !!} + +
+ + +
定期契約ID旧定期契約番号ゾーンID車室番号利用者ID利用者分類IDタグ・QR駐輪場ID有効期間S有効期間E駐輪場所ID防犯登録番号契約日時更新可能日解約日時減免措置定期有効月数シール印刷可能日請求金額車室割り当てフラグ授受日時授受金額授受フラグ決済トランザクションIDシール発行数シール発行許可解約フラグ収納企業コード共有先収納企業コード受付番号(更新元)契約更新済フラグ車種区分IDチェック用_フリガナチェック用_居住所郵便番号チェック用_携帯電話番号チェック用_自宅電話番号チェック用_旧会員番号 + 定期契約ID {!! $renderSortIcon('contract_qr_id') !!} + + 旧定期契約番号 {!! $renderSortIcon('old_contract_id') !!} + + 車室番号 {!! $renderSortIcon('pplace_no') !!} + + 利用者ID {!! $renderSortIcon('user_id') !!} + + 利用者分類ID {!! $renderSortIcon('user_categoryid') !!} + + タグ・QR {!! $renderSortIcon('tag_qr_flag') !!} + + 駐輪場ID {!! $renderSortIcon('park_id') !!} + + 予約日時 {!! $renderSortIcon('reserve_date') !!} + + 有効期間S {!! $renderSortIcon('contract_periods') !!} + + 有効期間E {!! $renderSortIcon('contract_periode') !!} + + 駐輪場所ID {!! $renderSortIcon('price_parkplaceid') !!} + + 防犯登録番号 {!! $renderSortIcon('user_securitynum') !!} + + 契約日時 {!! $renderSortIcon('contract_created_at') !!} + + 更新可能日 {!! $renderSortIcon('contract_updated_at') !!} + + 解約日時 {!! $renderSortIcon('contract_cancelday') !!} + + 減免措置 {!! $renderSortIcon('contract_reduction') !!} + + 定期有効月数 {!! $renderSortIcon('enable_months') !!} + + シール印刷可能日 {!! $renderSortIcon('printable_date') !!} + + 請求金額 {!! $renderSortIcon('billing_amount') !!} + + 車室割り当てフラグ {!! $renderSortIcon('pplace_allocation_flag') !!} + + 授受日時 {!! $renderSortIcon('contract_payment_day') !!} + + 授受金額 {!! $renderSortIcon('contract_money') !!} + + 授受フラグ {!! $renderSortIcon('contract_flag') !!} + + 決済トランザクションID {!! $renderSortIcon('settlement_transaction_id') !!} + + シール発行数 {!! $renderSortIcon('contract_seal_issue') !!} + + 収納企業コード {!! $renderSortIcon('storage_company_code') !!} + + 共有先収納企業コード {!! $renderSortIcon('share_storage_company_code') !!} + + 受付番号 {!! $renderSortIcon('accept_number') !!} + + (更新元)契約更新済フラグ {!! $renderSortIcon('update_flag') !!} + + 車種区分ID {!! $renderSortIcon('vehicle_type_id') !!} + + チェック用_フリガナ {!! $renderSortIcon('user_phonetic') !!} + + チェック用_居住所郵便番号 {!! $renderSortIcon('user_regident_zip') !!} + + チェック用_携帯電話番号 {!! $renderSortIcon('user_mobile') !!} + + チェック用_自宅電話番号 {!! $renderSortIcon('user_homephone') !!} + + チェック用_旧会員番号 {!! $renderSortIcon('old_member_number') !!} +
- + 編集
@@ -380,40 +537,54 @@ {{-- データ列 --}}
{{ $item->contract_qr_id }}{{ $item->old_contract_number ?? '' }}{{ $item->zone_id ?? '' }}{{ $item->room_number ?? '' }}{{ $item->user_id }}{{ $item->user_categoryid }}{{ $item->old_contract_id ?? '' }}{{ $item->pplace_no ?? '' }} + @if(!empty($item->user_seq)) + + {{ trim(($item->user_id ?? '') . ' ' . ($item->user_name ?? '')) }} + + @else + {{ $item->user_id ?? '' }} + @if(!empty($item->user_name)) +
{{ $item->user_name }}
+ @endif + @endif +
{{ $userCategoryLabel ?: $item->user_categoryid }} {{ $item->tag_qr_flag ? 'QR' : 'タグ' }} {{ $item->park_id }}{{ $item->valid_from ?? '' }}{{ $item->valid_to ?? '' }}{{ $item->price_arkplaceid ?? $item->price_parkplaceid ?? '' }}{{ $item->crime_prevention_registration_number ?? '' }}{{ $item->contract_created_at ?? '' }}{{ $item->renewable_date ?? '' }}{{ $item->contract_cancelday ?? '' }}{{ $item->reduction ?? '' }}{{ $item->contract_valid_months ?? '' }}{{ $item->label_printable_date ?? '' }}{{ $formatYmdHi($item->reserve_date ?? '') }}{{ $formatYmd($item->contract_periods ?? '') }}{{ $formatYmd($item->contract_periode ?? '') }}{{ $item->price_parkplaceid ?? '' }}{{ $item->user_securitynum ?? '' }}{{ $formatYmd($item->contract_created_at ?? '') }}{{ $formatYmd($item->contract_updated_at ?? '') }}{{ $formatYmd($item->contract_cancelday ?? '') }}{{ $item->contract_reduction ?? '' }}{{ $item->enable_months ?? '' }}{{ $formatYmd($item->printable_date ?? '') }} {{ $item->billing_amount ?? '' }}{{ ($item->assign_flag ?? null) === null ? '' : (($item->assign_flag) ? '割当済' : '未割当') }}{{ $item->receipt_delivery_date ?? '' }}{{ $item->receipt_delivery_amount ?? '' }} - {{ ($item->receipt_delivery_flag ?? null) === null ? '' : (($item->receipt_delivery_flag) ? '済' : '未') }} - {{ $item->payment_transaction_id ?? '' }}{{ $item->label_issue_count ?? '' }}{{ ($item->contract_permission ?? 0) ? '許可' : '未許可' }}{{ ($item->contract_cancel_flag ?? 0) ? 'キャンセル' : '-' }}{{ $item->company_code ?? '' }}{{ $item->shared_company_code ?? '' }}{{ ($item->pplace_allocation_flag ?? null) === null ? '' : (($item->pplace_allocation_flag) ? '割当済' : '未割当') }}{{ $formatYmd($item->contract_payment_day ?? '') }}{{ $item->contract_money ?? '' }}{{ ($item->contract_flag ?? null) === null ? '' : (($item->contract_flag) ? '済' : '未') }}{{ $item->settlement_transaction_id ?? '' }}{{ $item->contract_seal_issue ?? '' }}{{ $item->storage_company_code ?? '' }}{{ $item->share_storage_company_code ?? '' }} {{ $item->accept_number ?? '' }} {{ ($item->update_flag ?? 0) ? '更新済' : '未更新' }} {{ $item->vehicle_type_id ?? '' }}{{ $item->user_phonetic ?? '' }}{{ $item->chk_user_phonetic ?? $item->user_phonetic ?? '' }} {{ $item->user_regident_zip ?? '' }} {{ $item->user_mobile ?? '' }} {{ $item->user_homephone ?? '' }}
- - {{-- 下側のページャ(右寄せ) --}} -
- {{ $list->appends(['sort' => $sort, 'sort_type' => $sort_type])->links('pagination') }} -
@@ -465,67 +631,115 @@ - {{-- エクスポート用モーダル(確認のみ。リンク先でダウンロード) --}} - - {{-- 画面内スクリプト:インポートのファイル名表示、エクスポートのURL差し替え --}} - @endsection \ No newline at end of file