747 lines
32 KiB
PHP
747 lines
32 KiB
PHP
@extends('layouts.app')
|
||
@section('title', '定期契約マスタ')
|
||
|
||
@section('content')
|
||
<style>
|
||
/* 画面全体のフォント/サイズを統一(やや小さめ) */
|
||
.rc-page,
|
||
.rc-page .card,
|
||
.rc-page .form-control,
|
||
.rc-page .btn,
|
||
.rc-page table,
|
||
.rc-page .breadcrumb {
|
||
font-family: "Noto Sans JP", "Hiragino Kaku Gothic ProN", "Meiryo", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||
font-size: 13px;
|
||
line-height: 1.45;
|
||
}
|
||
|
||
/* フィルター:1行=左ラベル/右入力、を縦に積む */
|
||
.rc-filter .field {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: .6rem;
|
||
}
|
||
|
||
.rc-filter .label {
|
||
flex: 0 0 180px;
|
||
margin: 0;
|
||
color: #333;
|
||
font-weight: 600;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.rc-filter .input {
|
||
flex: 1 1 auto;
|
||
min-width: 220px;
|
||
}
|
||
|
||
.rc-filter .form-control,
|
||
.rc-filter .custom-select {
|
||
height: calc(2.0rem + 2px);
|
||
padding: .25rem .5rem;
|
||
}
|
||
|
||
.rc-filter .inline-range {
|
||
display: flex;
|
||
gap: .5rem;
|
||
align-items: center;
|
||
}
|
||
|
||
.rc-filter .tilde {
|
||
color: #666;
|
||
}
|
||
|
||
/* 一覧テーブル:斑馬(ゼブラ)無し、やや詰め気味 */
|
||
.rc-table th,
|
||
.rc-table td {
|
||
padding: .35rem .5rem;
|
||
font-size: 12px;
|
||
}
|
||
|
||
.rc-table thead th {
|
||
white-space: nowrap;
|
||
}
|
||
|
||
/* ツールバー:左にボタン群、右にページャ */
|
||
.rc-toolbar {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: .75rem;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.rc-toolbar .btn+.btn {
|
||
margin-left: .4rem;
|
||
}
|
||
|
||
/* 表頭=薄いグレー、本文=白 */
|
||
.rc-page .rc-table thead th {
|
||
background: #f2f2f2;
|
||
color: #333;
|
||
border-bottom-color: #ddd;
|
||
}
|
||
|
||
.rc-page .rc-table tbody td:not(.op-cell) {
|
||
background: #fff;
|
||
}
|
||
|
||
/* 操作列(チェック+編集) */
|
||
.rc-page .rc-table tbody td.op-cell {
|
||
background: #faebd7;
|
||
}
|
||
|
||
.rc-table thead th .sort-arrows {
|
||
display: inline-flex;
|
||
flex-direction: row;
|
||
align-items: center;
|
||
gap: 0.1rem;
|
||
margin-left: .2rem;
|
||
font-size: 12px;
|
||
line-height: 1;
|
||
font-weight: 700;
|
||
text-decoration: none;
|
||
letter-spacing: -5px; /* ↑↓を詰める */
|
||
}
|
||
.rc-table thead th .sort-arrows .up,
|
||
.rc-table thead th .sort-arrows .down {
|
||
color: #b5b5b5;
|
||
text-decoration: none;
|
||
}
|
||
.rc-table thead th.sorting_asc .sort-arrows .up {
|
||
color: #000;
|
||
}
|
||
.rc-table thead th.sorting_desc .sort-arrows .down {
|
||
color: #000;
|
||
}
|
||
</style>
|
||
|
||
<div class="rc-page">
|
||
<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>
|
||
<p class="text-muted mb-0">※この画面のデータは通常変更する必要はありません。</p>
|
||
</div>
|
||
</div>
|
||
|
||
<section class="content">
|
||
<div class="container-fluid">
|
||
|
||
{{-- 絞り込みフィルター(2カラム) --}}
|
||
<div class="card rc-filter">
|
||
<div class="card-header">
|
||
<h3 class="card-title">絞り込みフィルター</h3>
|
||
</div>
|
||
<div class="card-body">
|
||
<form action="{{ route('regularcontracts') }}" method="get" id="list-form">
|
||
@csrf
|
||
<input type="hidden" name="sort" id="sort" value="{{ $sort }}">
|
||
<input type="hidden" name="sort_type" id="sort_type" value="{{ $sort_type }}">
|
||
|
||
<div class="row">
|
||
{{-- 左カラム --}}
|
||
<div class="col-lg-6">
|
||
<div class="field">
|
||
<label class="label">利用者ID</label>
|
||
<div class="input"><input type="text" class="form-control" name="user_id" value="{{ $user_id ?? '' }}"
|
||
placeholder="123456"></div>
|
||
</div>
|
||
<div class="field">
|
||
<label class="label">利用者分類</label>
|
||
<div class="input">
|
||
<select class="form-control" name="user_categoryid">
|
||
<option value="">全て</option>
|
||
@foreach(($userTypeOptions ?? []) as $id => $label)
|
||
<option value="{{ $id }}" {{ (string)($user_categoryid ?? '') === (string) $id ? 'selected' : '' }}>
|
||
{{ $label }}
|
||
</option>
|
||
@endforeach
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div class="field">
|
||
<label class="label">タグシリアル</label>
|
||
<div class="input"><input type="text" class="form-control" name="user_tag_serial"
|
||
value="{{ $user_tag_serial ?? '' }}" placeholder="キーワード…"></div>
|
||
</div>
|
||
<div class="field">
|
||
<label class="label">フリガナ</label>
|
||
<div class="input"><input type="text" class="form-control" name="user_phonetic"
|
||
value="{{ $user_phonetic ?? '' }}" placeholder="キーワード…"></div>
|
||
</div>
|
||
<div class="field">
|
||
<label class="label">電話番号</label>
|
||
<div class="input"><input type="text" class="form-control" name="phone" value="{{ $phone ?? '' }}"
|
||
placeholder="携帯/自宅いずれも可"></div>
|
||
</div>
|
||
<div class="field">
|
||
<label class="label">メールアドレス</label>
|
||
<div class="input"><input type="text" class="form-control" name="email" value="{{ $email ?? '' }}" placeholder="キーワード…">
|
||
</div>
|
||
</div>
|
||
<div class="field">
|
||
<label class="label">ワークレコード</label>
|
||
<div class="input">
|
||
<select class="form-control" name="work_record">
|
||
<option value="0" {{ ($work_record ?? '0') === '0' ? 'selected' : '' }}>全レコード表示</option>
|
||
<option value="1" {{ ($work_record ?? '0') === '1' ? 'selected' : '' }}>ワークレコード非表示</option>
|
||
<option value="2" {{ ($work_record ?? '0') === '2' ? 'selected' : '' }}>ワークレコード表示</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div class="field">
|
||
<label class="label">定期契約ID</label>
|
||
<div class="input"><input type="text" class="form-control" name="contract_qr_id"
|
||
value="{{ $contract_qr_id ?? '' }}" placeholder="定期契約ID"></div>
|
||
</div>
|
||
<div class="field">
|
||
<label class="label">検索</label>
|
||
<div class="input"><input type="text" class="form-control" name="zone_keyword"
|
||
value="{{ $zone_keyword ?? '' }}" placeholder="ゾーンID, 車室番号, 旧会員番号"></div>
|
||
</div>
|
||
<div class="field">
|
||
<label class="label">関連住所入力あり</label>
|
||
<div class="input">
|
||
<div class="form-check" style="padding-left:0;">
|
||
<input type="checkbox" class="form-check-input" id="has_address" name="has_address" value="1" {{ !empty($has_address) ? 'checked' : '' }}>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{{-- 右カラム --}}
|
||
<div class="col-lg-6">
|
||
<div class="field">
|
||
<label class="label">駐輪場</label>
|
||
<div class="input">
|
||
<select class="form-control" name="park_id">
|
||
<option value="">全て</option>
|
||
@foreach(($parkOptions ?? []) as $id => $name)
|
||
<option value="{{ $id }}" {{ (string)($park_id ?? '') === (string) $id ? 'selected' : '' }}>
|
||
{{ $name }}
|
||
</option>
|
||
@endforeach
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div class="field">
|
||
<label class="label">予約日時</label>
|
||
<div class="input inline-range">
|
||
<input type="datetime-local" class="form-control" name="reserve_date_from"
|
||
value="{{ $reserve_date_from ?? '' }}">
|
||
<span class="tilde">~</span>
|
||
<input type="datetime-local" class="form-control" name="reserve_date_to"
|
||
value="{{ $reserve_date_to ?? '' }}">
|
||
</div>
|
||
</div>
|
||
<div class="field">
|
||
<label class="label">契約日時</label>
|
||
<div class="input inline-range">
|
||
<input type="datetime-local" class="form-control" name="contract_created_from"
|
||
value="{{ $contract_created_from ?? '' }}">
|
||
<span class="tilde">~</span>
|
||
<input type="datetime-local" class="form-control" name="contract_created_to"
|
||
value="{{ $contract_created_to ?? '' }}">
|
||
</div>
|
||
</div>
|
||
<div class="field">
|
||
<label class="label">解約日時</label>
|
||
<div class="input inline-range">
|
||
<input type="datetime-local" class="form-control" name="contract_canceled_from"
|
||
value="{{ $contract_canceled_from ?? '' }}">
|
||
<span class="tilde">~</span>
|
||
<input type="datetime-local" class="form-control" name="contract_canceled_to"
|
||
value="{{ $contract_canceled_to ?? '' }}">
|
||
</div>
|
||
</div>
|
||
<div class="field">
|
||
<label class="label">授受日時</label>
|
||
<div class="input inline-range">
|
||
<input type="datetime-local" class="form-control" name="receipt_delivery_from"
|
||
value="{{ $receipt_delivery_from ?? '' }}">
|
||
<span class="tilde">~</span>
|
||
<input type="datetime-local" class="form-control" name="receipt_delivery_to"
|
||
value="{{ $receipt_delivery_to ?? '' }}">
|
||
</div>
|
||
</div>
|
||
<div class="field">
|
||
<label class="label">定期有効月数</label>
|
||
<div class="input">
|
||
<select class="form-control" name="contract_valid_months">
|
||
<option value="">全て</option>
|
||
<option value="1" {{ (isset($contract_valid_months) && (string)$contract_valid_months === '1') ? 'selected' : '' }}>直近1ヶ月</option>
|
||
<option value="2" {{ (isset($contract_valid_months) && (string)$contract_valid_months === '2') ? 'selected' : '' }}>直近2ヶ月</option>
|
||
<option value="3" {{ (isset($contract_valid_months) && (string)$contract_valid_months === '3') ? 'selected' : '' }}>直近3ヶ月</option>
|
||
<option value="6" {{ (isset($contract_valid_months) && (string)$contract_valid_months === '6') ? 'selected' : '' }}>直近6ヶ月</option>
|
||
<option value="12" {{ (isset($contract_valid_months) && (string)$contract_valid_months === '12') ? 'selected' : '' }}>直近12ヶ月</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div class="field">
|
||
<label class="label">定期契約継続</label>
|
||
<div class="input">
|
||
<select class="form-control" name="update_flag">
|
||
<option value="0" {{ ($update_flag ?? '0') === '0' ? 'selected' : '' }}>全て</option>
|
||
<option value="1" {{ ($update_flag ?? '0') === '1' ? 'selected' : '' }}>継続契約</option>
|
||
<option value="2" {{ ($update_flag ?? '0') === '2' ? 'selected' : '' }}>それ以外(新規)</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div class="field">
|
||
<label class="label">名寄フリガナ</label>
|
||
<div class="input"><input type="text" class="form-control" name="merge_phonetic"
|
||
value="{{ $merge_phonetic ?? '' }}" placeholder="キーワード…"></div>
|
||
</div>
|
||
<div class="field">
|
||
<label class="label">ゾーン名検索</label>
|
||
<div class="input"><input type="text" class="form-control" name="zone_name"
|
||
value="{{ $zone_name ?? '' }}" placeholder="キーワード…"></div>
|
||
</div>
|
||
<div class="field">
|
||
<label class="label">タグ・QR</label>
|
||
<div class="input">
|
||
<select class="form-control" name="tag_qr_flag">
|
||
<option value="">全て</option>
|
||
<option value="0" {{ (isset($tag_qr_flag) && (string) $tag_qr_flag === '0') ? 'selected' : '' }}>タグ
|
||
</option>
|
||
<option value="1" {{ (isset($tag_qr_flag) && (string) $tag_qr_flag === '1') ? 'selected' : '' }}>QR
|
||
</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{{-- フィルターボタン(見た目統一) --}}
|
||
<div class="mt-2">
|
||
<button type="submit" class="btn btn-default">絞り込み</button>
|
||
<a href="{{ route('regularcontracts') }}" class="btn btn-default">解除</a>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
{{-- ツールバー:左=ボタン群、右=ページャ --}}
|
||
<div class="rc-toolbar mb-2">
|
||
<div class="left">
|
||
<a href="{{ route('regularcontracts_add') }}" class="btn btn-sm btn-default">新規</a>
|
||
<button type="button" class="btn btn-sm btn-default" id="btn-delete-selected">削除</button>
|
||
<button type="button" class="btn btn-sm btn-default" data-toggle="modal"
|
||
data-target="#importModal">インポート</button>
|
||
|
||
{{-- 3種のエクスポートは共通の確認モーダルを使い、data-url に出力先URLを渡す --}}
|
||
<button type="button" class="btn btn-sm btn-default js-export" data-url="{{ route('regularcontracts_export') }}">CSV出力</button>
|
||
|
||
<button type="button" class="btn btn-sm btn-default js-export" data-url="{{ route('regularcontracts_export', [], false) }}?type=smbc">SMBC出力</button>
|
||
|
||
<button type="button" class="btn btn-sm btn-default js-export" data-url="{{ route('regularcontracts_export', [], false) }}?type=city">役所提出用CSV出力</button>
|
||
</div>
|
||
<div class="right">
|
||
{{ $list->appends(request()->except('page'))->links('pagination') }}
|
||
</div>
|
||
</div>
|
||
|
||
<iframe id="dlFrame" name="dlFrame" style="width:0;height:0;border:0;visibility:hidden;"></iframe>
|
||
|
||
{{-- 一覧テーブル --}}
|
||
<form action="{{ route('regularcontracts_delete') }}" method="post" id="form_delete">
|
||
@csrf
|
||
<div class="table-responsive">
|
||
<table class="table table-bordered table-hover rc-table mb-0 text-nowrap">
|
||
@php
|
||
$currentSort = $sort ?? 'contract_id';
|
||
$currentDir = strtolower($sort_type ?? 'asc');
|
||
if (!in_array($currentDir, ['asc', 'desc'], true)) {
|
||
$currentDir = 'asc';
|
||
}
|
||
$sortClass = function (string $key) use ($currentSort, $currentDir) {
|
||
$base = 'sorting';
|
||
if ($currentSort === $key) {
|
||
return $base . ' ' . ($currentDir === 'asc' ? 'sorting_asc' : 'sorting_desc');
|
||
}
|
||
return $base;
|
||
};
|
||
@endphp
|
||
@php
|
||
$renderSortIcon = static function (string $key) {
|
||
return '<span class="sort-arrows"><span class="up">↑</span><span class="down">↓</span></span>';
|
||
};
|
||
@endphp
|
||
<thead>
|
||
<tr>
|
||
<th style="width:50px; text-align:right;"></th>
|
||
{{-- 操作列(チェック+編集。背景色を付与) --}}
|
||
<th style="width:120px">
|
||
<div class="d-flex align-items-center">
|
||
<input type="checkbox" id="check-all" class="mr-1">
|
||
<span></span>
|
||
</div>
|
||
</th>
|
||
<th class="text-right {{ $sortClass('contract_id') }}" sort="contract_id" style="white-space:nowrap;">
|
||
契約ID {!! $renderSortIcon('contract_id') !!}
|
||
</th>
|
||
{{-- 表頭(要件に合わせて網羅) --}}
|
||
<th class="text-right {{ $sortClass('contract_qr_id') }}" sort="contract_qr_id">
|
||
定期契約ID {!! $renderSortIcon('contract_qr_id') !!}
|
||
</th>
|
||
<th class="{{ $sortClass('old_contract_id') }}" sort="old_contract_id">
|
||
旧定期契約番号 {!! $renderSortIcon('old_contract_id') !!}
|
||
</th>
|
||
<th class="{{ $sortClass('pplace_no') }}" sort="pplace_no">
|
||
車室番号 {!! $renderSortIcon('pplace_no') !!}
|
||
</th>
|
||
<th class="{{ $sortClass('user_id') }}" sort="user_id">
|
||
利用者ID {!! $renderSortIcon('user_id') !!}
|
||
</th>
|
||
<th class="{{ $sortClass('user_categoryid') }}" sort="user_categoryid">
|
||
利用者分類ID {!! $renderSortIcon('user_categoryid') !!}
|
||
</th>
|
||
<th class="{{ $sortClass('tag_qr_flag') }}" sort="tag_qr_flag">
|
||
タグ・QR {!! $renderSortIcon('tag_qr_flag') !!}
|
||
</th>
|
||
<th class="text-right {{ $sortClass('park_id') }}" sort="park_id">
|
||
駐輪場ID {!! $renderSortIcon('park_id') !!}
|
||
</th>
|
||
<th class="{{ $sortClass('reserve_date') }}" sort="reserve_date">
|
||
予約日時 {!! $renderSortIcon('reserve_date') !!}
|
||
</th>
|
||
<th class="{{ $sortClass('contract_periods') }}" sort="contract_periods">
|
||
有効期間S {!! $renderSortIcon('contract_periods') !!}
|
||
</th>
|
||
<th class="{{ $sortClass('contract_periode') }}" sort="contract_periode">
|
||
有効期間E {!! $renderSortIcon('contract_periode') !!}
|
||
</th>
|
||
<th class="text-right {{ $sortClass('price_parkplaceid') }}" sort="price_parkplaceid">
|
||
駐輪場所ID {!! $renderSortIcon('price_parkplaceid') !!}
|
||
</th>
|
||
<th class="{{ $sortClass('user_securitynum') }}" sort="user_securitynum">
|
||
防犯登録番号 {!! $renderSortIcon('user_securitynum') !!}
|
||
</th>
|
||
<th class="{{ $sortClass('contract_created_at') }}" sort="contract_created_at">
|
||
契約日時 {!! $renderSortIcon('contract_created_at') !!}
|
||
</th>
|
||
<th class="{{ $sortClass('contract_updated_at') }}" sort="contract_updated_at">
|
||
更新可能日 {!! $renderSortIcon('contract_updated_at') !!}
|
||
</th>
|
||
<th class="{{ $sortClass('contract_cancelday') }}" sort="contract_cancelday">
|
||
解約日時 {!! $renderSortIcon('contract_cancelday') !!}
|
||
</th>
|
||
<th class="{{ $sortClass('contract_reduction') }}" sort="contract_reduction">
|
||
減免措置 {!! $renderSortIcon('contract_reduction') !!}
|
||
</th>
|
||
<th class="text-right {{ $sortClass('enable_months') }}" sort="enable_months">
|
||
定期有効月数 {!! $renderSortIcon('enable_months') !!}
|
||
</th>
|
||
<th class="{{ $sortClass('printable_date') }}" sort="printable_date">
|
||
シール印刷可能日 {!! $renderSortIcon('printable_date') !!}
|
||
</th>
|
||
<th class="text-right {{ $sortClass('billing_amount') }}" sort="billing_amount">
|
||
請求金額 {!! $renderSortIcon('billing_amount') !!}
|
||
</th>
|
||
<th class="{{ $sortClass('pplace_allocation_flag') }}" sort="pplace_allocation_flag">
|
||
車室割り当てフラグ {!! $renderSortIcon('pplace_allocation_flag') !!}
|
||
</th>
|
||
<th class="{{ $sortClass('contract_payment_day') }}" sort="contract_payment_day">
|
||
授受日時 {!! $renderSortIcon('contract_payment_day') !!}
|
||
</th>
|
||
<th class="text-right {{ $sortClass('contract_money') }}" sort="contract_money">
|
||
授受金額 {!! $renderSortIcon('contract_money') !!}
|
||
</th>
|
||
<th class="{{ $sortClass('contract_flag') }}" sort="contract_flag">
|
||
授受フラグ {!! $renderSortIcon('contract_flag') !!}
|
||
</th>
|
||
<th class="{{ $sortClass('settlement_transaction_id') }}" sort="settlement_transaction_id">
|
||
決済トランザクションID {!! $renderSortIcon('settlement_transaction_id') !!}
|
||
</th>
|
||
<th class="text-right {{ $sortClass('contract_seal_issue') }}" sort="contract_seal_issue">
|
||
シール発行数 {!! $renderSortIcon('contract_seal_issue') !!}
|
||
</th>
|
||
<th class="{{ $sortClass('storage_company_code') }}" sort="storage_company_code">
|
||
収納企業コード {!! $renderSortIcon('storage_company_code') !!}
|
||
</th>
|
||
<th class="{{ $sortClass('share_storage_company_code') }}" sort="share_storage_company_code">
|
||
共有先収納企業コード {!! $renderSortIcon('share_storage_company_code') !!}
|
||
</th>
|
||
<th class="{{ $sortClass('accept_number') }}" sort="accept_number">
|
||
受付番号 {!! $renderSortIcon('accept_number') !!}
|
||
</th>
|
||
<th class="{{ $sortClass('update_flag') }}" sort="update_flag">
|
||
(更新元)契約更新済フラグ {!! $renderSortIcon('update_flag') !!}
|
||
</th>
|
||
<th class="{{ $sortClass('vehicle_type_id') }}" sort="vehicle_type_id">
|
||
車種区分ID {!! $renderSortIcon('vehicle_type_id') !!}
|
||
</th>
|
||
<th class="{{ $sortClass('user_phonetic') }}" sort="user_phonetic">
|
||
チェック用_フリガナ {!! $renderSortIcon('user_phonetic') !!}
|
||
</th>
|
||
<th class="{{ $sortClass('user_regident_zip') }}" sort="user_regident_zip">
|
||
チェック用_居住所郵便番号 {!! $renderSortIcon('user_regident_zip') !!}
|
||
</th>
|
||
<th class="{{ $sortClass('user_mobile') }}" sort="user_mobile">
|
||
チェック用_携帯電話番号 {!! $renderSortIcon('user_mobile') !!}
|
||
</th>
|
||
<th class="{{ $sortClass('user_homephone') }}" sort="user_homephone">
|
||
チェック用_自宅電話番号 {!! $renderSortIcon('user_homephone') !!}
|
||
</th>
|
||
<th class="{{ $sortClass('old_member_number') }}" sort="old_member_number">
|
||
チェック用_旧会員番号 {!! $renderSortIcon('old_member_number') !!}
|
||
</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
@php
|
||
$formatYmd = static function ($value) {
|
||
if (empty($value)) {
|
||
return '';
|
||
}
|
||
try {
|
||
return \Illuminate\Support\Carbon::parse($value)->format('Y-m-d');
|
||
} catch (\Throwable $e) {
|
||
return mb_substr((string) $value, 0, 10);
|
||
}
|
||
};
|
||
$formatYmdHi = static function ($value) {
|
||
if (empty($value)) {
|
||
return '';
|
||
}
|
||
try {
|
||
return \Illuminate\Support\Carbon::parse($value)->format('Y-m-d H:i');
|
||
} catch (\Throwable $e) {
|
||
return mb_substr((string) $value, 0, 16);
|
||
}
|
||
};
|
||
@endphp
|
||
@foreach($list as $item)
|
||
<tr>
|
||
|
||
<td class="text-right">{{ $loop->iteration }}</td>
|
||
|
||
{{-- 操作列:チェック + 編集(背景色つき) --}}
|
||
<td class="op-cell">
|
||
<div class="d-flex align-items-center">
|
||
<input type="checkbox" class="mr-2 row-check" name="ids[]" value="{{ $item->contract_id }}">
|
||
<a href="{{ route('regularcontracts_edit', ['contract_id' => $item->contract_id]) }}"
|
||
class="btn btn-sm btn-default">編集</a>
|
||
</div>
|
||
</td>
|
||
|
||
{{-- 先頭の並び替え列(行の contract_id を表示) --}}
|
||
<td class="text-right">{{ $item->contract_id }}</td>
|
||
{{-- データ列 --}}
|
||
<td class="text-right">{{ $item->contract_qr_id }}</td>
|
||
<td>{{ $item->old_contract_id ?? '' }}</td>
|
||
<td>{{ $item->pplace_no ?? '' }}</td>
|
||
<td>
|
||
@if(!empty($item->user_seq))
|
||
<a href="{{ route('users_edit', ['seq' => $item->user_seq]) }}" class="text-primary">
|
||
{{ trim(($item->user_id ?? '') . ' ' . ($item->user_name ?? '')) }}
|
||
</a>
|
||
@else
|
||
{{ $item->user_id ?? '' }}
|
||
@if(!empty($item->user_name))
|
||
<div class="text-muted small">{{ $item->user_name }}</div>
|
||
@endif
|
||
@endif
|
||
</td>
|
||
@php
|
||
$userCategoryLabel = collect([
|
||
$item->usertype_subject1 ?? '',
|
||
$item->usertype_subject2 ?? '',
|
||
$item->usertype_subject3 ?? '',
|
||
])->filter(fn ($v) => $v !== '')->implode('/');
|
||
@endphp
|
||
<td>{{ $userCategoryLabel ?: $item->user_categoryid }}</td>
|
||
<td>{{ $item->tag_qr_flag ? 'QR' : 'タグ' }}</td>
|
||
<td class="text-right">{{ $item->park_id }}</td>
|
||
<td>{{ $formatYmdHi($item->reserve_date ?? '') }}</td>
|
||
<td>{{ $formatYmd($item->contract_periods ?? '') }}</td>
|
||
<td>{{ $formatYmd($item->contract_periode ?? '') }}</td>
|
||
<td class="text-right">{{ $item->price_parkplaceid ?? '' }}</td>
|
||
<td>{{ $item->user_securitynum ?? '' }}</td>
|
||
<td>{{ $formatYmd($item->contract_created_at ?? '') }}</td>
|
||
<td>{{ $formatYmd($item->contract_updated_at ?? '') }}</td>
|
||
<td>{{ $formatYmd($item->contract_cancelday ?? '') }}</td>
|
||
<td>{{ $item->contract_reduction ?? '' }}</td>
|
||
<td class="text-right">{{ $item->enable_months ?? '' }}</td>
|
||
<td>{{ $formatYmd($item->printable_date ?? '') }}</td>
|
||
<td class="text-right">{{ $item->billing_amount ?? '' }}</td>
|
||
<td>{{ ($item->pplace_allocation_flag ?? null) === null ? '' : (($item->pplace_allocation_flag) ? '割当済' : '未割当') }}</td>
|
||
<td>{{ $formatYmd($item->contract_payment_day ?? '') }}</td>
|
||
<td class="text-right">{{ $item->contract_money ?? '' }}</td>
|
||
<td>{{ ($item->contract_flag ?? null) === null ? '' : (($item->contract_flag) ? '済' : '未') }}</td>
|
||
<td>{{ $item->settlement_transaction_id ?? '' }}</td>
|
||
<td class="text-right">{{ $item->contract_seal_issue ?? '' }}</td>
|
||
<td>{{ $item->storage_company_code ?? '' }}</td>
|
||
<td>{{ $item->share_storage_company_code ?? '' }}</td>
|
||
<td>{{ $item->accept_number ?? '' }}</td>
|
||
<td>{{ ($item->update_flag ?? 0) ? '更新済' : '未更新' }}</td>
|
||
<td>{{ $item->vehicle_type_id ?? '' }}</td>
|
||
<td>{{ $item->chk_user_phonetic ?? $item->user_phonetic ?? '' }}</td>
|
||
<td>{{ $item->user_regident_zip ?? '' }}</td>
|
||
<td>{{ $item->user_mobile ?? '' }}</td>
|
||
<td>{{ $item->user_homephone ?? '' }}</td>
|
||
<td>{{ $item->old_member_number ?? '' }}</td>
|
||
</tr>
|
||
@endforeach
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
|
||
{{-- インポート用モーダル(ファイル選択) --}}
|
||
<div class="modal fade" id="importModal" tabindex="-1" role="dialog" aria-labelledby="importModalLabel"
|
||
aria-hidden="true">
|
||
<div class="modal-dialog modal-sm" role="document">
|
||
<div class="modal-content">
|
||
<div class="modal-header py-2">
|
||
<h5 class="modal-title" id="importModalLabel">確認</h5>
|
||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
|
||
aria-hidden="true">×</span></button>
|
||
</div>
|
||
<form method="post" action="{{ route('regularcontracts_import') }}" enctype="multipart/form-data">
|
||
@csrf
|
||
<div class="modal-body">
|
||
<p class="mb-2 text-sm">
|
||
データをインポートします。既存データを上書きする場合はテンプレートに従い識別列を設定してください。<br>
|
||
新規追加のみの場合は識別列を空欄のままインポートしてください。
|
||
</p>
|
||
<div class="custom-file">
|
||
<input type="file" name="file" id="importFile" class="custom-file-input" accept=".csv,.xlsx,.xls,.tsv,.txt"
|
||
required>
|
||
<label class="custom-file-label" for="importFile">ファイルの選択</label>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer py-2">
|
||
<button type="submit" class="btn btn-primary btn-sm">はい</button>
|
||
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal">いいえ</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{{-- 画面内スクリプト:インポートのファイル名表示、エクスポートのURL差し替え --}}
|
||
<script>
|
||
// インポート:選択したファイル名をラベルに反映
|
||
document.addEventListener('change', function (e) {
|
||
if (e.target && e.target.id === 'importFile') {
|
||
var label = e.target.nextElementSibling;
|
||
if (label) label.textContent = e.target.files.length ? e.target.files[0].name : 'ファイルの選択';
|
||
}
|
||
});
|
||
|
||
// エクスポート:モーダル表示時に押下ボタンの data-url を「はい」へセット
|
||
(function () {
|
||
var exportModal = document.getElementById('exportModal');
|
||
var deleteForm = document.getElementById('form_delete');
|
||
var deleteBtn = document.getElementById('btn-delete-selected');
|
||
var masterCheckbox = document.getElementById('check-all');
|
||
var rowSelector = '.row-check';
|
||
|
||
var exportButtons = document.querySelectorAll('.js-export');
|
||
if (exportButtons.length) {
|
||
exportButtons.forEach(function (btn) {
|
||
btn.addEventListener('click', function () {
|
||
var url = btn.getAttribute('data-url');
|
||
if (!url) {
|
||
return;
|
||
}
|
||
var doExport = function () {
|
||
var iframe = document.getElementById('dlFrame');
|
||
if (iframe) {
|
||
iframe.src = url;
|
||
} else {
|
||
window.location.href = url;
|
||
}
|
||
};
|
||
if (window.jQuery && typeof window.jQuery.confirm === 'function') {
|
||
window.jQuery.confirm({
|
||
title: '確認ダイアログ。',
|
||
content: 'CSVファイルを出力します。よろしいですか? はい/いいえ',
|
||
buttons: {
|
||
ok: {
|
||
text: 'はい',
|
||
btnClass: 'btn-primary',
|
||
keys: ['enter'],
|
||
action: doExport
|
||
},
|
||
いいえ: function () {}
|
||
}
|
||
});
|
||
} else if (confirm('CSVファイルを出力します。よろしいですか? はい/いいえ')) {
|
||
doExport();
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
if (deleteBtn && deleteForm) {
|
||
deleteBtn.addEventListener('click', function () {
|
||
var checked = document.querySelectorAll(rowSelector + ':checked');
|
||
if (!checked.length) {
|
||
alert('削除する定期契約を選択してください。');
|
||
return;
|
||
}
|
||
|
||
var submitDelete = function () {
|
||
deleteForm.submit();
|
||
};
|
||
|
||
if (window.jQuery && typeof window.jQuery.confirm === 'function') {
|
||
window.jQuery.confirm({
|
||
title: '確認ダイアログ。',
|
||
content: '削除してよろしいですか? はい/いいえ',
|
||
buttons: {
|
||
ok: {
|
||
text: 'はい',
|
||
btnClass: 'btn-primary',
|
||
keys: ['enter'],
|
||
action: submitDelete
|
||
},
|
||
いいえ: function () {}
|
||
}
|
||
});
|
||
} else if (confirm('削除してよろしいですか? はい/いいえ')) {
|
||
submitDelete();
|
||
}
|
||
});
|
||
}
|
||
|
||
if (masterCheckbox) {
|
||
var updateMasterState = function () {
|
||
var allRows = document.querySelectorAll(rowSelector);
|
||
var checkedRows = document.querySelectorAll(rowSelector + ':checked');
|
||
masterCheckbox.checked = allRows.length > 0 && checkedRows.length === allRows.length;
|
||
};
|
||
|
||
masterCheckbox.addEventListener('change', function () {
|
||
var allRows = document.querySelectorAll(rowSelector);
|
||
allRows.forEach(function (checkbox) {
|
||
checkbox.checked = masterCheckbox.checked;
|
||
});
|
||
});
|
||
|
||
document.addEventListener('change', function (e) {
|
||
if (e.target && e.target.matches(rowSelector)) {
|
||
updateMasterState();
|
||
}
|
||
});
|
||
|
||
updateMasterState();
|
||
}
|
||
})();
|
||
</script>
|
||
@endsection |