krgm.so-manager-dev.com/app/Http/Controllers/Admin/PriceController.php
kin.rinzen 9a0f8a8846
All checks were successful
Deploy main / deploy (push) Successful in 22s
「指摘対応」SWA-95/SWA-62/SWA-78
2025-10-10 23:30:56 +09:00

311 lines
11 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Http\Controllers\Admin;
use App\Http\Requests\PriceRequest;
use App\Models\Park;
use App\Models\Price;
use App\Models\Pplace;
use App\Models\Psection;
use App\Models\Ptype;
use App\Models\Usertype;
use App\Models\Utils;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Response;
class PriceController extends Controller
{
public function list(Request $request)
{
$inputs = [
'isExport' => 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()
{
$filename = '駐輪場所、料金マスタ' . now()->format('YmdHis') . '.csv';
$file = fopen($filename, 'w+');
fwrite($file, "\xEF\xBB\xBF"); // BOM追加UTF-8
$columns = [
'駐輪場所ID',
'駐輪場ID',
'商品名',
'期間',
'利用者分類ID',
'駐輪料金(税込)',
'車種区分ID',
'駐輪分類ID',
'駐車車室ID',
];
fputcsv($file, $columns);
$data = Price::all();
foreach ($data as $item) {
fputcsv($file, [
$item->price_parkplaceid, // 駐輪場所ID
$item->park_id, // 駐輪場ID
optional($item->getUserType())->print_name, // 利用者分類名
$item->price_month, // 期間
optional($item->getUserType())->print_name, // 利用者分類ID
$item->price, // 駐輪料金(税込)
optional($item->getPSection())->psection_subject, // 車種区分名
optional($item->getPType())->ptype_subject, // 駐輪分類名
$item->pplace_id, // 駐車車室ID
]);
}
fclose($file);
$headers = [
"Content-Type" => "text/csv; charset=UTF-8",
"Content-Disposition" => "attachment; filename={$filename}",
];
return response()->download($filename, $filename, $headers)->deleteFileAfterSend(true);
}
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',
]);
}
}