diff --git a/app/Http/Controllers/Admin/ManagerController.php b/app/Http/Controllers/Admin/ManagerController.php index fbaa639..f7fe9ae 100644 --- a/app/Http/Controllers/Admin/ManagerController.php +++ b/app/Http/Controllers/Admin/ManagerController.php @@ -31,39 +31,38 @@ class ManagerController extends Controller return view('admin.managers.list', compact('list','sort','sort_type')); } - /** 新規(GET:画面表示 / POST:登録) */ + /** 新規登録画面・登録処理 */ public function add(Request $request) { if ($request->isMethod('post')) { - $data = $this->validated($request); + $validated = $this->validated($request); + + Manager::create($validated); - $manager = Manager::create($data); return redirect() - ->route('managers_info', ['manager_id' => $manager->manager_id]) + ->route('managers') ->with('success', '登録しました。'); } - // 画面に渡す初期値 - $view = $this->viewVars(); - return view('admin.managers.add', $view); + return view('admin.managers.add', $this->viewVars()); } /** 編集(GET:画面表示 / POST:更新) */ - public function edit(Request $request, $manager_id) + public function edit(Request $request, $id) { - $manager = Manager::findOrFail($manager_id); + $manager = Manager::findOrFail($id); if ($request->isMethod('post')) { - $data = $this->validated($request); - $manager->fill($data)->save(); + $validated = $this->validated($request); + + $manager->update($validated); return redirect() - ->route('managers_info', ['manager_id' => $manager->manager_id]) - ->with('success', '更新しました。'); + ->route('managers') + ->with('success', '更新されました。'); } - $view = $this->viewVars($manager); - return view('admin.managers.edit', $view); + return view('admin.managers.edit', $this->viewVars($manager)); } /** 詳細(閲覧) */ @@ -78,13 +77,19 @@ class ManagerController extends Controller public function delete(Request $request) { $ids = (array) $request->input('pk', []); - if (!$ids) return back()->with('error', '削除対象が選択されていません。'); + if (!$ids) { + return back()->with('error', '削除対象が選択されていません。'); + } DB::transaction(fn() => Manager::whereIn('manager_id', $ids)->delete()); - return back()->with('success', '削除しました。'); + // 一覧画面へリダイレクト + 成功メッセージ + return redirect() + ->route('managers') + ->with('success', '削除しました。'); } + /** CSV出力 */ public function export(): StreamedResponse { @@ -167,22 +172,32 @@ class ManagerController extends Controller } } - /* ======================== private helpers ======================== */ - - /** バリデーション */ + /** バリデーション + 前処理 */ private function validated(Request $request): array { + // 電話番号を全角に変換(半角入力があっても自動で全角に揃える) + $request->merge([ + 'manager_tel' => mb_convert_kana($request->input('manager_tel'), 'N') // 半角数字→全角数字 + ]); + + // select の未選択 "" を null に補正 + foreach (['manager_device2'] as $f) { + if ($request->input($f) === "") { + $request->merge([$f => null]); + } + } + return $request->validate([ - 'manager_name' => ['required','string','max:255'], - 'manager_type' => ['nullable','string','max:255'], - 'manager_parkid' => ['nullable','integer','exists:park,park_id'], // テーブル名に合わせて - 'manager_device1' => ['nullable','integer','exists:device,device_id'], + 'manager_name' => ['required','string','max:32'], + 'manager_type' => ['required','string','max:10'], + 'manager_parkid' => ['required','integer','exists:park,park_id'], + 'manager_device1' => ['required','integer','exists:device,device_id'], 'manager_device2' => ['nullable','integer','exists:device,device_id'], - 'manager_mail' => ['nullable','email','max:255'], - 'manager_tel' => ['nullable','string','max:255'], + 'manager_mail' => ['nullable','email','max:128'], + 'manager_tel' => ['required','regex:/^[0-9]+$/u','max:13'], // 全角数字のみ 'manager_alert1' => ['nullable','boolean'], 'manager_alert2' => ['nullable','boolean'], - 'manager_quit_flag' => ['nullable','boolean'], + 'manager_quit_flag' => ['required','in:0,1'], 'manager_quitday' => ['nullable','date'], ], [], [ 'manager_name' => '駐輪場管理者名', @@ -199,6 +214,7 @@ class ManagerController extends Controller ]); } + /** 画面に渡す変数を作る(_form.blade.php が個別変数を参照するため) */ private function viewVars(?Manager $m = null): array { diff --git a/app/Http/Controllers/Admin/PaymentController.php b/app/Http/Controllers/Admin/PaymentController.php index 79d7bba..3e940fb 100644 --- a/app/Http/Controllers/Admin/PaymentController.php +++ b/app/Http/Controllers/Admin/PaymentController.php @@ -44,6 +44,7 @@ class PaymentController extends Controller 'payment_inquiryname' => 'nullable|string|max:255', 'payment_inquirytel' => 'nullable|string|max:255', 'payment_time' => 'nullable|string|max:255', + ]); // 登録データ作成 @@ -52,7 +53,7 @@ class PaymentController extends Controller Payment::create($data); - return redirect()->route('payments')->with('success', '登録しました'); + return redirect()->route('payments')->with('success', '登録しました。'); } return view('admin.payments.add', [ @@ -80,7 +81,7 @@ class PaymentController extends Controller $payment->update($data); - return redirect()->route('payments')->with('success', '更新しました'); + return redirect()->route('payments')->with('success', '更新しました。'); } return view('admin.payments.edit', [ @@ -108,11 +109,22 @@ class PaymentController extends Controller */ public function delete(Request $request) { - if ($request->has('ids')) { - Payment::whereIn('payment_id', $request->ids)->delete(); - return redirect()->route('payments')->with('success', '削除しました'); + $pk = $request->input('pk', []); + + // 配列に統一 + $ids = is_array($pk) ? $pk : [$pk]; + + // 数字チェック + $ids = array_values(array_filter($ids, fn($v) => preg_match('/^\d+$/', (string) $v))); + + if (empty($ids)) { + return redirect()->route('payments')->with('error', '削除対象が選択されていません。'); } - return redirect()->route('payments')->with('error', '削除対象が選択されていません'); + + // 削除 + Payment::whereIn('payment_id', $ids)->delete(); + + return redirect()->route('payments')->with('success', '削除しました。'); } /** diff --git a/app/Http/Controllers/Admin/SettlementTransactionController.php b/app/Http/Controllers/Admin/SettlementTransactionController.php index 93ae8ed..996e373 100644 --- a/app/Http/Controllers/Admin/SettlementTransactionController.php +++ b/app/Http/Controllers/Admin/SettlementTransactionController.php @@ -16,9 +16,14 @@ class SettlementTransactionController extends Controller */ public function list(Request $request) { + // 解除ボタンが押された場合 → 一覧にリダイレクトして検索条件リセット + if ($request->input('action') === 'unlink') { + return redirect()->route('settlement_transactions'); + } + $q = SettlementTransaction::query(); - // --- 絞り込み(必要なら増やせます) + // --- 絞り込み $contractId = $request->input('contract_id'); $status = trim((string)$request->input('status', '')); $from = $request->input('from'); // 支払日時 from @@ -59,6 +64,7 @@ class SettlementTransactionController extends Controller ]); } + /** * 新規 * ルート: settlement_transactions_add diff --git a/app/Http/Controllers/Admin/TaxController.php b/app/Http/Controllers/Admin/TaxController.php index ff1b639..5880c53 100644 --- a/app/Http/Controllers/Admin/TaxController.php +++ b/app/Http/Controllers/Admin/TaxController.php @@ -58,59 +58,59 @@ class TaxController extends Controller } public function add(Request $request) -{ - if ($request->isMethod('post')) { - $data = $request->validate([ - 'tax_percent' => ['required', 'numeric', 'min:0', 'max:1000'], - 'tax_day' => ['required', 'date', 'unique:tax,tax_day'], - ]); - $data['operator_id'] = optional(\Auth::user())->ope_id ?? null; - $data['tax_percent'] = number_format((float)$data['tax_percent'], 2, '.', ''); - \App\Models\Tax::create($data); + { + if ($request->isMethod('post')) { + $data = $request->validate([ + 'tax_percent' => ['required', 'numeric', 'min:0', 'max:1000'], + 'tax_day' => ['required', 'date', 'unique:tax,tax_day'], + ]); + $data['operator_id'] = optional(\Auth::user())->ope_id ?? null; + $data['tax_percent'] = number_format((float)$data['tax_percent'], 2, '.', ''); + \App\Models\Tax::create($data); - return redirect()->route('tax')->with('success', '登録しました'); + return redirect()->route('tax')->with('success', '登録しました。'); + } + + return view('admin.tax.add', [ + 'tax' => null, + 'isEdit' => false, + 'isInfo' => false, + ]); } - return view('admin.tax.add', [ - 'tax' => null, - 'isEdit' => false, - 'isInfo' => false, - ]); -} + public function edit(int $tax_id, Request $request) + { + $tax = \App\Models\Tax::findOrFail($tax_id); -public function edit(int $tax_id, Request $request) -{ - $tax = \App\Models\Tax::findOrFail($tax_id); + if ($request->isMethod('post')) { + $data = $request->validate([ + 'tax_percent' => ['required', 'numeric', 'min:0', 'max:1000'], + 'tax_day' => ['required', 'date', 'unique:tax,tax_day,' . $tax->tax_id . ',tax_id'], + ]); + $data['operator_id'] = optional(\Auth::user())->ope_id ?? null; + $data['tax_percent'] = number_format((float)$data['tax_percent'], 2, '.', ''); + $tax->update($data); - if ($request->isMethod('post')) { - $data = $request->validate([ - 'tax_percent' => ['required', 'numeric', 'min:0', 'max:1000'], - 'tax_day' => ['required', 'date', 'unique:tax,tax_day,' . $tax->tax_id . ',tax_id'], + return redirect()->route('tax')->with('success', '更新しました。'); + } + + return view('admin.tax.edit', [ + 'tax' => $tax, + 'isEdit' => true, + 'isInfo' => false, ]); - $data['operator_id'] = optional(\Auth::user())->ope_id ?? null; - $data['tax_percent'] = number_format((float)$data['tax_percent'], 2, '.', ''); - $tax->update($data); - - return redirect()->route('tax')->with('success', '更新しました'); } - return view('admin.tax.edit', [ - 'tax' => $tax, - 'isEdit' => true, - 'isInfo' => false, - ]); -} + public function info(int $tax_id) + { + $tax = \App\Models\Tax::findOrFail($tax_id); -public function info(int $tax_id) -{ - $tax = \App\Models\Tax::findOrFail($tax_id); - - return view('admin.tax.info', [ - 'tax' => $tax, - 'isEdit' => false, - 'isInfo' => true, - ]); -} + return view('admin.tax.info', [ + 'tax' => $tax, + 'isEdit' => false, + 'isInfo' => true, + ]); + } /** @@ -119,166 +119,175 @@ public function info(int $tax_id) */ public function delete(Request $request) { - $ids = (array) $request->input('ids', []); + + $pk = $request->input('pk', []); + + // 配列に統一 + $ids = is_array($pk) ? $pk : [$pk]; + + // 数字チェック $ids = array_values(array_filter($ids, fn($v) => preg_match('/^\d+$/', (string) $v))); if (empty($ids)) { return redirect()->route('tax')->with('error', '削除対象が選択されていません。'); } + // 削除 Tax::whereIn('tax_id', $ids)->delete(); - return redirect()->route('tax')->with('success', '削除しました'); + return redirect()->route('tax')->with('success', '削除しました。'); } - /** - * CSVインポート - * カラム想定: tax_percent, tax_day - * - 1行目はヘッダ可 - * - tax_day をキーとして「存在すれば更新 / 無ければ作成」 - */ - public function import(Request $request) - { - $request->validate([ - 'file' => ['required', 'file', 'mimetypes:text/plain,text/csv,text/tsv', 'max:2048'], - ]); - $path = $request->file('file')->getRealPath(); - if (!$path || !is_readable($path)) { - return redirect()->route('tax')->with('error', 'ファイルを読み込めません。'); - } - $created = 0; - $updated = 0; - $skipped = 0; + // /** + // * CSVインポート + // * カラム想定: tax_percent, tax_day + // * - 1行目はヘッダ可 + // * - tax_day をキーとして「存在すれば更新 / 無ければ作成」 + // */ + // public function import(Request $request) + // { + // $request->validate([ + // 'file' => ['required', 'file', 'mimetypes:text/plain,text/csv,text/tsv', 'max:2048'], + // ]); - DB::beginTransaction(); - try { - if (($fp = fopen($path, 'r')) !== false) { - $line = 0; - while (($row = fgetcsv($fp)) !== false) { - $line++; + // $path = $request->file('file')->getRealPath(); + // if (!$path || !is_readable($path)) { + // return redirect()->route('tax')->with('error', 'ファイルを読み込めません。'); + // } - // 空行スキップ - if (count($row) === 1 && trim((string) $row[0]) === '') { - continue; - } + // $created = 0; + // $updated = 0; + // $skipped = 0; - // ヘッダ行っぽい場合(1行目に 'tax_percent' を含む) - if ($line === 1) { - $joined = strtolower(implode(',', $row)); - if (str_contains($joined, 'tax_percent') && str_contains($joined, 'tax_day')) { - continue; // ヘッダスキップ - } - } + // DB::beginTransaction(); + // try { + // if (($fp = fopen($path, 'r')) !== false) { + // $line = 0; + // while (($row = fgetcsv($fp)) !== false) { + // $line++; - // 取り出し(列数が足りない場合スキップ) - $percent = $row[0] ?? null; - $day = $row[1] ?? null; - if ($percent === null || $day === null) { - $skipped++; - continue; - } + // // 空行スキップ + // if (count($row) === 1 && trim((string) $row[0]) === '') { + // continue; + // } - // 正規化 & 検証 - $percent = trim((string) $percent); - $percent = rtrim($percent, '%'); - $percent = preg_replace('/[^\d.]/', '', $percent) ?? '0'; - $percentF = (float) $percent; - if ($percentF < 0) { - $skipped++; - continue; - } - $percentF = (float) number_format($percentF, 2, '.', ''); + // // ヘッダ行っぽい場合(1行目に 'tax_percent' を含む) + // if ($line === 1) { + // $joined = strtolower(implode(',', $row)); + // if (str_contains($joined, 'tax_percent') && str_contains($joined, 'tax_day')) { + // continue; // ヘッダスキップ + // } + // } - $day = date('Y-m-d', strtotime((string) $day)); - if (!$day) { - $skipped++; - continue; - } + // // 取り出し(列数が足りない場合スキップ) + // $percent = $row[0] ?? null; + // $day = $row[1] ?? null; + // if ($percent === null || $day === null) { + // $skipped++; + // continue; + // } - // upsert: 適用日ユニーク運用 - $existing = Tax::whereDate('tax_day', $day)->first(); - $payload = [ - 'tax_percent' => $percentF, - 'tax_day' => $day, - 'operator_id' => optional(Auth::user())->ope_id ?? null, - ]; + // // 正規化 & 検証 + // $percent = trim((string) $percent); + // $percent = rtrim($percent, '%'); + // $percent = preg_replace('/[^\d.]/', '', $percent) ?? '0'; + // $percentF = (float) $percent; + // if ($percentF < 0) { + // $skipped++; + // continue; + // } + // $percentF = (float) number_format($percentF, 2, '.', ''); - if ($existing) { - $existing->update($payload); - $updated++; - } else { - Tax::create($payload); - $created++; - } - } - fclose($fp); - } + // $day = date('Y-m-d', strtotime((string) $day)); + // if (!$day) { + // $skipped++; + // continue; + // } - DB::commit(); - return redirect()->route('tax')->with('success', "インポート完了:新規 {$created} 件、更新 {$updated} 件、スキップ {$skipped} 件"); - } catch (\Throwable $e) { - DB::rollBack(); - return redirect()->route('tax')->with('error', 'インポートに失敗しました:' . $e->getMessage()); - } - } + // // upsert: 適用日ユニーク運用 + // $existing = Tax::whereDate('tax_day', $day)->first(); + // $payload = [ + // 'tax_percent' => $percentF, + // 'tax_day' => $day, + // 'operator_id' => optional(Auth::user())->ope_id ?? null, + // ]; - /** - * CSVエクスポート:現在の絞り込み/ソート条件を反映 - */ - public function export(Request $request): StreamedResponse - { - $query = Tax::query(); + // if ($existing) { + // $existing->update($payload); + // $updated++; + // } else { + // Tax::create($payload); + // $created++; + // } + // } + // fclose($fp); + // } - $keyword = trim((string) $request->input('kw')); - if ($keyword !== '') { - $query->where('tax_percent', 'like', "%{$keyword}%"); - } - $from = $request->input('from'); - $to = $request->input('to'); - if ($from) { - $query->whereDate('tax_day', '>=', $from); - } - if ($to) { - $query->whereDate('tax_day', '<=', $to); - } + // DB::commit(); + // return redirect()->route('tax')->with('success', "インポート完了:新規 {$created} 件、更新 {$updated} 件、スキップ {$skipped} 件"); + // } catch (\Throwable $e) { + // DB::rollBack(); + // return redirect()->route('tax')->with('error', 'インポートに失敗しました:' . $e->getMessage()); + // } + // } - $sort = $request->input('sort', 'tax_day'); - $type = strtolower($request->input('sort_type', 'desc')); - $allow = ['tax_day', 'tax_percent', 'updated_at', 'created_at', 'tax_id']; - if (!in_array($sort, $allow, true)) { - $sort = 'tax_day'; - } - if (!in_array($type, ['asc', 'desc'], true)) { - $type = 'desc'; - } - $query->orderBy($sort, $type); + // /** + // * CSVエクスポート:現在の絞り込み/ソート条件を反映 + // */ + // public function export(Request $request): StreamedResponse + // { + // $query = Tax::query(); - $filename = 'tax_' . now()->format('Ymd_His') . '.csv'; + // $keyword = trim((string) $request->input('kw')); + // if ($keyword !== '') { + // $query->where('tax_percent', 'like', "%{$keyword}%"); + // } + // $from = $request->input('from'); + // $to = $request->input('to'); + // if ($from) { + // $query->whereDate('tax_day', '>=', $from); + // } + // if ($to) { + // $query->whereDate('tax_day', '<=', $to); + // } - return response()->streamDownload(function () use ($query) { - $out = fopen('php://output', 'w'); - // Header(設計書の主要カラム) - fputcsv($out, ['消費税ID', '消費税率', '適用日', '登録日時', '更新日時', '更新オペレータID']); - $query->chunk(500, function ($rows) use ($out) { - foreach ($rows as $r) { - fputcsv($out, [ - $r->tax_id, - // 画面仕様に合わせたい場合は getDisplayTaxPercentAttribute() に置換可 - is_numeric($r->tax_percent) - ? number_format((float) $r->tax_percent, 2, '.', '') - : (string) $r->tax_percent, - optional($r->tax_day)->format('Y-m-d'), - optional($r->created_at)->format('Y-m-d H:i:s'), - optional($r->updated_at)->format('Y-m-d H:i:s'), - $r->operator_id, - ]); - } - }); - fclose($out); - }, $filename, [ - 'Content-Type' => 'text/csv; charset=UTF-8', - ]); - } + // $sort = $request->input('sort', 'tax_day'); + // $type = strtolower($request->input('sort_type', 'desc')); + // $allow = ['tax_day', 'tax_percent', 'updated_at', 'created_at', 'tax_id']; + // if (!in_array($sort, $allow, true)) { + // $sort = 'tax_day'; + // } + // if (!in_array($type, ['asc', 'desc'], true)) { + // $type = 'desc'; + // } + // $query->orderBy($sort, $type); + + // $filename = 'tax_' . now()->format('Ymd_His') . '.csv'; + + // return response()->streamDownload(function () use ($query) { + // $out = fopen('php://output', 'w'); + // // Header(設計書の主要カラム) + // fputcsv($out, ['消費税ID', '消費税率', '適用日', '登録日時', '更新日時', '更新オペレータID']); + // $query->chunk(500, function ($rows) use ($out) { + // foreach ($rows as $r) { + // fputcsv($out, [ + // $r->tax_id, + // // 画面仕様に合わせたい場合は getDisplayTaxPercentAttribute() に置換可 + // is_numeric($r->tax_percent) + // ? number_format((float) $r->tax_percent, 2, '.', '') + // : (string) $r->tax_percent, + // optional($r->tax_day)->format('Y-m-d'), + // optional($r->created_at)->format('Y-m-d H:i:s'), + // optional($r->updated_at)->format('Y-m-d H:i:s'), + // $r->operator_id, + // ]); + // } + // }); + // fclose($out); + // }, $filename, [ + // 'Content-Type' => 'text/csv; charset=UTF-8', + // ]); + // } } diff --git a/app/Models/Price.php b/app/Models/Price.php index 3ad4daf..ec12629 100644 --- a/app/Models/Price.php +++ b/app/Models/Price.php @@ -42,9 +42,14 @@ class Price extends Model public static function search($inputs) { - $query = self::query(); - - // 検索条件 + $query = self::query() + ->select( + 'price_a.*', + \DB::raw("CONCAT_WS('/', usertype.usertype_subject1, usertype.usertype_subject2, usertype.usertype_subject3) as user_category_name") + ) + ->leftJoin('usertype', 'price_a.user_categoryid', '=', 'usertype.user_categoryid'); + + // ソート対象カラム $allowedSortColumns = [ 'price_parkplaceid', // 駐車場所ID 'park_id', // 駐輪場ID @@ -57,7 +62,6 @@ class Price extends Model 'pplace_id', // 駐車車室ID ]; - // ソート指定 $sortColumn = $inputs['sort'] ?? ''; $sortType = strtolower($inputs['sort_type'] ?? 'asc'); @@ -68,13 +72,14 @@ class Price extends Model $query->orderBy($sortColumn, $sortType); } - // データ取得 return $inputs['isExport'] ? $query->get() : $query->paginate(\App\Utils::item_per_page ?? 20); } + + public static function getByPk($pk) { return self::find($pk); diff --git a/app/Models/SettlementTransaction.php b/app/Models/SettlementTransaction.php index d615b18..ac0c917 100644 --- a/app/Models/SettlementTransaction.php +++ b/app/Models/SettlementTransaction.php @@ -24,4 +24,11 @@ class SettlementTransaction extends Model 'stamp_flag', 'md5_string', ]; + + // 日付型キャスト + protected $casts = [ + 'created_at' => 'datetime', + 'updated_at' => 'datetime', + 'pay_date' => 'datetime', + ]; } diff --git a/resources/lang/ja/validation.php b/resources/lang/ja/validation.php index 3fdbdb2..a98133a 100644 --- a/resources/lang/ja/validation.php +++ b/resources/lang/ja/validation.php @@ -390,7 +390,14 @@ return [ //SWA-98 'contract_allowable_city_id' => '契約許容市区マスタID', 'contract_allowable_city_name' => '許容市区名', - 'same_district_flag' => '隣接区フラグ', + 'same_district_flag' => '隣接区フラグ', +//SWA-67 + 'tax_id' => '消費税ID', + 'tax_percent' => '消費税率', + 'tax_day' => '適用日', +//SWA-80 + 'payment_companyname' => '事業者名', + ], ]; diff --git a/resources/views/admin/managers/_form.blade.php b/resources/views/admin/managers/_form.blade.php index eeea66c..dbce158 100644 --- a/resources/views/admin/managers/_form.blade.php +++ b/resources/views/admin/managers/_form.blade.php @@ -17,67 +17,64 @@ @endif -@php - $isAddPage = request()->routeIs('managers_add'); // 新規ページなら true -@endphp -