332 lines
11 KiB
PHP
332 lines
11 KiB
PHP
<?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 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(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',
|
||
]);
|
||
}
|
||
|
||
|
||
|
||
|
||
} |