This commit is contained in:
parent
5df6c31b86
commit
0a5e21cd9a
111
app/Http/Controllers/Admin/ReductionConfirmMasterController.php
Normal file
111
app/Http/Controllers/Admin/ReductionConfirmMasterController.php
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Admin;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\Park;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class ReductionConfirmMasterController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 減免確認マスタ画面を表示
|
||||||
|
*
|
||||||
|
* @param Request $request park_id をクエリパラメータで受け取る
|
||||||
|
* @return \Illuminate\View\View
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
// park_id の検証
|
||||||
|
$request->validate([
|
||||||
|
'park_id' => 'required|integer|exists:park,park_id',
|
||||||
|
], [
|
||||||
|
'park_id.required' => '駐輪場IDは必須です。',
|
||||||
|
'park_id.integer' => '駐輪場IDは整数である必要があります。',
|
||||||
|
'park_id.exists' => '指定された駐輪場が見つかりません。',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$parkId = (int) $request->input('park_id');
|
||||||
|
|
||||||
|
// 駐輪場情報を取得
|
||||||
|
$park = Park::where('park_id', $parkId)->firstOrFail();
|
||||||
|
|
||||||
|
// reduction_confirm を主テーブルとして、usertype と JOIN して一覧を取得
|
||||||
|
// WHERE park_id = ? で対象駐輪場のレコードのみ取得
|
||||||
|
$reductionData = DB::table('reduction_confirm')
|
||||||
|
->leftJoin('usertype', 'reduction_confirm.user_categoryid', '=', 'usertype.user_categoryid')
|
||||||
|
->where('reduction_confirm.park_id', $parkId)
|
||||||
|
->orderBy('reduction_confirm.user_categoryid', 'asc')
|
||||||
|
->select(
|
||||||
|
'reduction_confirm.park_id',
|
||||||
|
'reduction_confirm.user_categoryid',
|
||||||
|
'reduction_confirm.reduction_confirm_type',
|
||||||
|
'usertype.usertype_subject1',
|
||||||
|
'usertype.usertype_subject2',
|
||||||
|
'usertype.usertype_subject3'
|
||||||
|
)
|
||||||
|
->paginate(50);
|
||||||
|
|
||||||
|
return view('admin.reduction_confirm.index', [
|
||||||
|
'park' => $park,
|
||||||
|
'parkId' => $parkId,
|
||||||
|
'reductionData' => $reductionData,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 減免確認情報を一括更新
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
|
*/
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
// バリデーション
|
||||||
|
$validated = $request->validate([
|
||||||
|
'park_id' => 'required|integer|exists:park,park_id',
|
||||||
|
'reduction_confirm_type' => 'array',
|
||||||
|
'reduction_confirm_type.*' => 'in:0,1,2',
|
||||||
|
], [
|
||||||
|
'park_id.required' => '駐輪場IDは必須です。',
|
||||||
|
'park_id.integer' => '駐輪場IDは整数である必要があります。',
|
||||||
|
'park_id.exists' => '指定された駐輪場が見つかりません。',
|
||||||
|
'reduction_confirm_type.*.in' => '減免確認種別は0, 1, 2 のいずれかである必要があります。',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$parkId = (int) $validated['park_id'];
|
||||||
|
$types = $validated['reduction_confirm_type'] ?? [];
|
||||||
|
|
||||||
|
// ログイン中のオペレータID取得
|
||||||
|
$opeId = auth()->user()->ope_id ?? null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// トランザクションで更新処理を実行
|
||||||
|
DB::transaction(function () use ($parkId, $types, $opeId) {
|
||||||
|
foreach ($types as $userCategoryId => $type) {
|
||||||
|
DB::table('reduction_confirm')
|
||||||
|
->where('park_id', $parkId)
|
||||||
|
->where('user_categoryid', (int) $userCategoryId)
|
||||||
|
->update([
|
||||||
|
'reduction_confirm_type' => (int) $type,
|
||||||
|
'updated_at' => now(),
|
||||||
|
'ope_id' => $opeId,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return redirect()->route('reduction_confirm.index', ['park_id' => $parkId])
|
||||||
|
->with('success', '減免確認マスタを更新しました。');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
\Log::error('ReductionConfirm update failed', [
|
||||||
|
'park_id' => $parkId,
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return back()->withErrors(['error' => '更新に失敗しました。管理者にお問い合わせください。'])
|
||||||
|
->withInput();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
48
app/Models/ReductionMaster.php
Normal file
48
app/Models/ReductionMaster.php
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
|
class ReductionMaster extends Model
|
||||||
|
{
|
||||||
|
const CREATED_AT = 'created_at';
|
||||||
|
const UPDATED_AT = 'updated_at';
|
||||||
|
|
||||||
|
protected $table = 'reduction_confirm';
|
||||||
|
protected $primaryKey = null; // 複合キーを使用
|
||||||
|
public $incrementing = false;
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'park_id',
|
||||||
|
'user_categoryid',
|
||||||
|
'reduction_check_type',
|
||||||
|
'operator_id',
|
||||||
|
'created_at',
|
||||||
|
'updated_at',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 複合キー (park_id, user_categoryid) で既存レコードを検索または作成
|
||||||
|
*/
|
||||||
|
public static function findOrCreateByKeys($parkId, $userCategoryId)
|
||||||
|
{
|
||||||
|
return self::where('park_id', $parkId)
|
||||||
|
->where('user_categoryid', $userCategoryId)
|
||||||
|
->first();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* レコード保存時に operator_id を自動設定
|
||||||
|
*/
|
||||||
|
public static function boot()
|
||||||
|
{
|
||||||
|
parent::boot();
|
||||||
|
self::saving(function (ReductionMaster $model) {
|
||||||
|
if (!isset($model->operator_id) || $model->operator_id === null) {
|
||||||
|
$model->operator_id = Auth::user()->ope_id ?? null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -22,7 +22,8 @@
|
|||||||
|
|
||||||
{{-- ▼ 編集フォーム --}}
|
{{-- ▼ 編集フォーム --}}
|
||||||
<div class="card shadow">
|
<div class="card shadow">
|
||||||
<form id="park-edit-form" method="POST" action="{{ route('parks.update', $park->park_id) }}" enctype="multipart/form-data">
|
<form id="park-edit-form" method="POST" action="{{ route('parks.update', $park->park_id) }}"
|
||||||
|
enctype="multipart/form-data">
|
||||||
@csrf
|
@csrf
|
||||||
@method('PUT')
|
@method('PUT')
|
||||||
|
|
||||||
@ -30,7 +31,9 @@
|
|||||||
{{-- ▼ ボタンエリア(上部) --}}
|
{{-- ▼ ボタンエリア(上部) --}}
|
||||||
<div class="mt-2">
|
<div class="mt-2">
|
||||||
<button type="button" class="btn btn-default mt-2 btn-submit">登録</button>
|
<button type="button" class="btn btn-default mt-2 btn-submit">登録</button>
|
||||||
<a href="javascript:void(0)" class="btn btn-default mt-2">減免確認編集</a>
|
<a href="{{ route('reduction_confirm.index', ['park_id' => $park->park_id]) }}" class="btn btn-default mt-2">
|
||||||
|
減免確認編集
|
||||||
|
</a>
|
||||||
<a href="javascript:void(0)" class="btn btn-default mt-2">駐輪状況編集</a>
|
<a href="javascript:void(0)" class="btn btn-default mt-2">駐輪状況編集</a>
|
||||||
<button type="button" class="btn btn-default mt-2">削除</button>
|
<button type="button" class="btn btn-default mt-2">削除</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
64
resources/views/admin/reduction_confirm/_form.blade.php
Normal file
64
resources/views/admin/reduction_confirm/_form.blade.php
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
{{-- 減免確認マスタテーブル行(各利用者分類) --}}
|
||||||
|
@php
|
||||||
|
// reduction_confirm テーブルから取得したレコード
|
||||||
|
$userCategoryId = $row->user_categoryid;
|
||||||
|
$checkType = $row->reduction_confirm_type;
|
||||||
|
$oldCheckType = old("reduction_confirm_type.$userCategoryId", $checkType);
|
||||||
|
|
||||||
|
// 学生分類かどうかを判定
|
||||||
|
$isStudent = $row->usertype_subject1 === '学生';
|
||||||
|
$rowClass = $isStudent ? 'table-secondary' : '';
|
||||||
|
$isDisabled = $isStudent;
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
<tr class="{{ $rowClass }}">
|
||||||
|
<td class="text-center">{{ $userCategoryId }}</td>
|
||||||
|
<td>{{ $row->usertype_subject1 ?? '-' }}</td>
|
||||||
|
<td>{{ $row->usertype_subject2 ?? '-' }}</td>
|
||||||
|
<td>{{ $row->usertype_subject3 ?? '-' }}</td>
|
||||||
|
<td>
|
||||||
|
<div class="d-flex justify-content-center gap-3">
|
||||||
|
{{-- 確認しない(0) --}}
|
||||||
|
<div class="custom-control custom-radio">
|
||||||
|
<input type="radio"
|
||||||
|
id="check_type_{{ $userCategoryId }}_0"
|
||||||
|
name="reduction_confirm_type[{{ $userCategoryId }}]"
|
||||||
|
value="0"
|
||||||
|
class="custom-control-input"
|
||||||
|
@checked($oldCheckType == 0)
|
||||||
|
@disabled($isDisabled)>
|
||||||
|
<label class="custom-control-label" for="check_type_{{ $userCategoryId }}_0">
|
||||||
|
確認しない
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- 年1回(1) --}}
|
||||||
|
<div class="custom-control custom-radio">
|
||||||
|
<input type="radio"
|
||||||
|
id="check_type_{{ $userCategoryId }}_1"
|
||||||
|
name="reduction_confirm_type[{{ $userCategoryId }}]"
|
||||||
|
value="1"
|
||||||
|
class="custom-control-input"
|
||||||
|
@checked($oldCheckType == 1)
|
||||||
|
@disabled($isDisabled)>
|
||||||
|
<label class="custom-control-label" for="check_type_{{ $userCategoryId }}_1">
|
||||||
|
年1回
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- 毎更新時(2) --}}
|
||||||
|
<div class="custom-control custom-radio">
|
||||||
|
<input type="radio"
|
||||||
|
id="check_type_{{ $userCategoryId }}_2"
|
||||||
|
name="reduction_confirm_type[{{ $userCategoryId }}]"
|
||||||
|
value="2"
|
||||||
|
class="custom-control-input"
|
||||||
|
@checked($oldCheckType == 2)
|
||||||
|
@disabled($isDisabled)>
|
||||||
|
<label class="custom-control-label" for="check_type_{{ $userCategoryId }}_2">
|
||||||
|
毎更新時
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
152
resources/views/admin/reduction_confirm/index.blade.php
Normal file
152
resources/views/admin/reduction_confirm/index.blade.php
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
@section('title', '減免確認マスタ')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<!-- Content Header -->
|
||||||
|
<div class="content-header">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<h1 class="m-0 text-dark">減免確認マスタ</h1>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<ol class="breadcrumb float-sm-right text-sm">
|
||||||
|
<li class="breadcrumb-item"><a href="{{ route('home') }}">ホーム</a></li>
|
||||||
|
<li class="breadcrumb-item active">減免確認マスタ</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<section class="content">
|
||||||
|
<div class="container-fluid">
|
||||||
|
{{-- エラーメッセージ表示 --}}
|
||||||
|
@if ($errors->any())
|
||||||
|
<div class="alert alert-danger alert-dismissible fade show" role="alert">
|
||||||
|
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
<h4 class="alert-heading">エラーが発生しました</h4>
|
||||||
|
<ul class="mb-0">
|
||||||
|
@foreach ($errors->all() as $error)
|
||||||
|
<li>{{ $error }}</li>
|
||||||
|
@endforeach
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
{{-- 成功メッセージ表示 --}}
|
||||||
|
@if (session('success'))
|
||||||
|
<div class="alert alert-success alert-dismissible fade show" role="alert">
|
||||||
|
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
{{ session('success') }}
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<!-- 駐輪場情報カード -->
|
||||||
|
<div class="col-lg-12 px-0">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h3 class="card-title">駐輪場情報</h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row align-items-center">
|
||||||
|
<div class="col-md-2">
|
||||||
|
<label class="font-weight-bold mb-0">駐輪場名</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-10">
|
||||||
|
<div class="park-name-display">
|
||||||
|
{{ $park->park_name ?? '' }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{{--
|
||||||
|
<div class="text-right mb-2">
|
||||||
|
全 {{ $list->total() }} 件中 {{ $list->firstItem() }}〜{{ $list->lastItem() }} 件を表示
|
||||||
|
</div>
|
||||||
|
<div class="ml-auto">
|
||||||
|
{{ $list->appends(keepUserListQuery())->links('pagination') }}
|
||||||
|
</div>
|
||||||
|
--}}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- 減免確認マスタ テーブル -->
|
||||||
|
|
||||||
|
<div class="col-lg-12 px-0 ">
|
||||||
|
<form action="{{ route('reduction_confirm.store') }}" method="POST" id="reduction-form">
|
||||||
|
{{-- 登録ボタン --}}
|
||||||
|
<div class="container-fluid mb20">
|
||||||
|
<button type="submit" class="btn btn-primary mt-2 btn-submit">登録</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@csrf
|
||||||
|
<input type="hidden" name="park_id" value="{{ $parkId }}">
|
||||||
|
|
||||||
|
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<thead class="thead-light">
|
||||||
|
<tr>
|
||||||
|
<th style="width: 5%; text-align: center;">利用者分類</th>
|
||||||
|
<th style="width: 10%;">分類名1</th>
|
||||||
|
<th style="width: 10%;">分類名2</th>
|
||||||
|
<th style="width: 10%;">分類名3</th>
|
||||||
|
<th style="width: 20%; text-align: center;">減免確認種別</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@forelse ($reductionData as $row)
|
||||||
|
@include('admin.reduction_confirm._form', ['row' => $row])
|
||||||
|
@empty
|
||||||
|
<tr>
|
||||||
|
<td colspan="5" class="text-center text-muted">
|
||||||
|
利用者分類がありません。
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforelse
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.gap-3 {
|
||||||
|
gap: 1rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-control {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-control-label {
|
||||||
|
margin-bottom: 0;
|
||||||
|
margin-left: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.park-name-display {
|
||||||
|
background-color: #e9ecef;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 10px 14px;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #6c757d;
|
||||||
|
width: fit-content;
|
||||||
|
min-width: 320px;
|
||||||
|
}
|
||||||
|
.sample03-wrapper {
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@endsection
|
||||||
@ -42,6 +42,7 @@ use App\Http\Controllers\Admin\MailTemplateController;
|
|||||||
use App\Http\Controllers\Admin\InvSettingController;
|
use App\Http\Controllers\Admin\InvSettingController;
|
||||||
use App\Http\Controllers\Admin\ZoneController;
|
use App\Http\Controllers\Admin\ZoneController;
|
||||||
use App\Http\Controllers\Admin\PplaceController;
|
use App\Http\Controllers\Admin\PplaceController;
|
||||||
|
use App\Http\Controllers\Admin\ReductionConfirmMasterController;
|
||||||
use App\Http\Controllers\HomeController;
|
use App\Http\Controllers\HomeController;
|
||||||
use App\Http\Controllers\Auth\EmailOtpController;
|
use App\Http\Controllers\Auth\EmailOtpController;
|
||||||
|
|
||||||
@ -276,6 +277,10 @@ Route::middleware('auth')->group(function () {
|
|||||||
Route::match(['get', 'post'], '/usertypes/import', [UsertypeController::class, 'import'])->name('usertypes_import');
|
Route::match(['get', 'post'], '/usertypes/import', [UsertypeController::class, 'import'])->name('usertypes_import');
|
||||||
Route::match(['get', 'post'], '/usertypes/export', [UsertypeController::class, 'export'])->name('usertypes_export');
|
Route::match(['get', 'post'], '/usertypes/export', [UsertypeController::class, 'export'])->name('usertypes_export');
|
||||||
|
|
||||||
|
// 減免確認マスタ
|
||||||
|
Route::get('/reduction-confirm-master', [ReductionConfirmMasterController::class, 'index'])->name('reduction_confirm.index');
|
||||||
|
Route::post('/reduction-confirm-master', [ReductionConfirmMasterController::class, 'store'])->name('reduction_confirm.store');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 契約者一覧
|
// 契約者一覧
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user