0, 'sort' => $request->input('sort', ''), // ソート対象カラム 'sort_type' => $request->input('sort_type', ''), // 昇順/降順 'page' => $request->get('page', 1), ]; // Price::search 内で orderBy を反映させる $inputs['list'] = Price::search($inputs); if ($inputs['list']->total() > 0 && $inputs['page'] > $inputs['list']->lastPage()) { return redirect()->route('prices'); } $dataList = $this->getDataDropList(); $inputs = array_merge($inputs, $dataList); return view('admin.prices.list', $inputs); } public function add(Request $request) { if ($request->isMethod('get')) { return view('admin.prices.add', array_merge( $this->getDataDropList(), [ 'record' => new Price(), 'isEdit' => false, ] )); } $request->merge([ 'pplace_id' => mb_convert_kana($request->input('pplace_id'), 'n'), ]); $validated = $this->validateRequest($request); $created = false; \DB::transaction(function () use ($validated, &$created) { $price = new Price(); $price->fill($validated); $created = $price->save(); }); return redirect()->route('prices') ->with($created ? 'success' : 'error', $created ? '登録しました。' : '登録に失敗しました。'); } public function edit(Request $request, $id) { $price = Price::getByPk($id); if (!$price) { abort(404); } if ($request->isMethod('get')) { return view('admin.prices.edit', array_merge( $this->getDataDropList(), [ 'record' => $price, 'isEdit' => true, ] )); } $request->merge([ 'pplace_id' => mb_convert_kana($request->input('pplace_id'), 'n'), ]); $validated = $this->validateRequest($request, $id); $updated = false; \DB::transaction(function () use ($validated, &$updated, $price) { $price->fill($validated); $updated = $price->save(); }); return redirect()->route('prices') ->with($updated ? 'success' : 'error', $updated ? '更新しました。' : '更新に失敗しました。'); } public function delete(Request $request, $id = null) { // 一覧画面(checkbox で複数削除) $ids = $request->input('pk'); // 編集画面(単体削除) if ($id) { $ids = [$id]; } // 削除対象が空 if (empty($ids)) { return redirect()->route('prices')->with('error', '削除対象が選択されていません。'); } // 削除処理 Price::destroy($ids); return redirect()->route('prices')->with('success', '削除しました。'); } public static function deleteByPk($ids) { if (!is_array($ids)) { $ids = [$ids]; } return self::whereIn('price_parkplaceid', $ids)->delete(); } public function export(Request $request) { $headers = [ "Content-type" => "text/csv;charset=UTF-8", 'Content-Encoding: UTF-8', "Content-Disposition" => "attachment; filename=file.csv", "Pragma" => "no-cache", "Cache-Control" => "must-revalidate, post-check=0, pre-check=0", "Expires" => "0" ]; $query = Price::query(); // 🚩 条件付きエクスポート(park_id) if ($request->filled('park_id')) { $query->where('park_id', $request->input('park_id')); } // ソート if ($request->filled('sort')) { $query->orderBy($request->input('sort'), $request->input('sort_type', 'asc')); } $dataExport = $query->get(); $columns = [ __('駐車場所ID'), __('商品名'), __('期間'), __('駐輪場ID'), __('駐輪場名'), __('車種区分ID'), __('車種区分'), __('駐輪分類ID'), __('駐輪分類'), __('利用者分類ID'), __('利用者分類'), __('駐車車室ID'), __('駐輪料金(税込)'), ]; $filename = "駐輪場所、料金マスタ.csv"; $file = fopen($filename, 'w+'); fputcsv($file, $columns); foreach ($dataExport as $items) { fputcsv($file, [ $items->price_parkplaceid, $items->prine_name, $items->price_month, $items->park_id, optional($items->getPark())->park_name, $items->psection_id, optional($items->getPSection())->psection_subject, $items->price_ptypeid, optional($items->getPType())->ptype_subject, $items->user_categoryid, optional($items->getUserType())->print_name, $items->pplace_id, $items->price, ]); } fclose($file); return Response::download($filename, $filename, $headers); } public function import(Request $request) { $file = $request->file('file'); if (empty($file)) { return redirect()->route('prices')->with('error', __('CSVファイルを選択してください。')); } $data = Utils::csvToArray($file); $type = true; $msg = ''; $record = 0; DB::beginTransaction(); try { // 先清空数据(全置換仕様なら残す) Price::query()->delete(); $col = 13; // CSV 項目数 foreach ($data as $key => $items) { $record = $key + 2; // エラー行番号(ヘッダ行を考慮) // 項目数チェック if (count($items) != $col) { $type = false; $msg = "行:{$record} 列数が一致しません。"; break; } // 必須チェック if (empty($items[0])) { $type = false; $msg = "行:{$record} 駐車場所IDが未設定です。"; break; } if (empty($items[1])) { $type = false; $msg = "行:{$record} 商品名が未設定です。"; break; } if (empty($items[2])) { $type = false; $msg = "行:{$record} 期間が未設定です。"; break; } if (empty($items[3])) { $type = false; $msg = "行:{$record} 駐輪場IDが未設定です。"; break; } if (empty($items[5])) { $type = false; $msg = "行:{$record} 車種区分IDが未設定です。"; break; } if (empty($items[7])) { $type = false; $msg = "行:{$record} 駐輪分類IDが未設定です。"; break; } if (empty($items[9])) { $type = false; $msg = "行:{$record} 利用者分類IDが未設定です。"; break; } if (empty($items[11])) { $type = false; $msg = "行:{$record} 駐車車室IDが未設定です。"; break; } if (empty($items[12])) { $type = false; $msg = "行:{$record} 駐輪料金が未設定です。"; break; } // マスタ存在チェック if (!Park::where('park_id', $items[3])->exists()) { $type = false; $msg = "行:{$record} 駐輪場IDが存在しません。"; break; } if (!Psection::where('psection_id', $items[5])->exists()) { $type = false; $msg = "行:{$record} 車種区分IDが存在しません。"; break; } if (!Ptype::where('ptype_id', $items[7])->exists()) { $type = false; $msg = "行:{$record} 駐輪分類IDが存在しません。"; break; } if (!Usertype::where('user_categoryid', $items[9])->exists()) { $type = false; $msg = "行:{$record} 利用者分類IDが存在しません。"; break; } // TODO: 駐車車室ID チェック(pplace_id) // 保存 $row = new Price(); $row->price_parkplaceid = $items[0]; $row->prine_name = $items[1]; $row->price_month = $items[2]; $row->park_id = $items[3]; $row->psection_id = $items[5]; $row->price_ptypeid = $items[7]; $row->user_categoryid = $items[9]; $row->pplace_id = $items[11]; $row->price = $items[12]; if (!$row->save()) { $type = false; $msg = "行:{$record} データ保存に失敗しました。"; break; } } } catch (\Exception $e) { $type = false; $msg = "行:{$record} 予期せぬエラー: ".$e->getMessage(); } if ($type) { DB::commit(); return redirect()->route('prices')->with('success', __('インポートが正常に完了しました。')); } else { DB::rollBack(); return redirect()->route('prices')->with('error', $msg); } } public function info(Request $request, $id) { return $this->edit($request, $id, 'admin.prices.info'); } public function getDataDropList() { $data['parks'] = Park::getList() ; $data['psections'] = Psection::getList() ; $data['ptypes'] = Ptype::getList() ; $data['userTypes'] = Usertype::getList() ; $data['pplaces'] = Pplace::getList() ; return $data; } /** * Price バリデーション共通 */ private function validateRequest(Request $request): array { return $request->validate([ 'prine_name' => 'required|string|max:255', 'price_month' => 'required|int', 'park_id' => 'required|int', 'psection_id' => 'required|int', 'price_ptypeid' => 'required|int', 'user_categoryid' => 'required|int', 'pplace_id' => 'nullable|int', 'park_number' => 'nullable|int', 'park_standard' => 'nullable|int', 'park_limit' => 'nullable|int', 'price' => 'required|numeric', 'operator_id' => 'nullable|int', ]); } }