From 628317d04f389b5a237b63de8375476439297788 Mon Sep 17 00:00:00 2001 From: Yuka Higashide Date: Tue, 20 Jan 2026 17:59:48 +0900 Subject: [PATCH] =?UTF-8?q?=E5=AE=9A=E6=9C=9F=E5=A5=91=E7=B4=84=E5=B1=A5?= =?UTF-8?q?=E6=AD=B4=E7=A2=BA=E8=AA=8D=E3=80=81=E9=A0=98=E5=8F=8E=E6=9B=B8?= =?UTF-8?q?=E5=AE=9B=E5=90=8D=E5=85=A5=E5=8A=9B=E7=94=BB=E9=9D=A2=E5=AF=BE?= =?UTF-8?q?=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Controllers/ReceiptController.php | 231 +++++-- .../Controllers/RegularContractController.php | 39 +- app/Http/Middleware/ManagementMiddleware.php | 3 +- public/assets/css/mypage/app.css | 566 ++++++++++++++++-- resources/lang/ja/messages.php | 69 +++ resources/views/layouts/app.blade.php | 4 - resources/views/receipt/input.blade.php | 31 +- resources/views/receipt/pdf.blade.php | 59 +- .../views/regular_contract/history.blade.php | 42 +- routes/web.php | 2 +- 10 files changed, 872 insertions(+), 174 deletions(-) create mode 100644 resources/lang/ja/messages.php diff --git a/app/Http/Controllers/ReceiptController.php b/app/Http/Controllers/ReceiptController.php index 6d939a1..4ed15c2 100644 --- a/app/Http/Controllers/ReceiptController.php +++ b/app/Http/Controllers/ReceiptController.php @@ -1,68 +1,114 @@ format('Y-m-d H:i:s') . " 未認証ユーザーによるアクセス(セッション切れ): 領収書宛名入力画面アクセス"); + return redirect()->guest('/login'); } - $user = DB::table('user')->where('user_id', $user_id)->first(); + // ヘッダー表示のためユーザー名取得 + $user_name = DB::table('user')->where('user_id', $user_id)->value('user_name'); - \Log::info('領収書宛名入力画面にアクセス', [ - 'user_id' => $user_id, - ]); + $management = session('management'); + $management_id = $management->management_id; + + // セキュリティのため、そのユーザーの契約のみアクセス可能 + $contract = DB::table('regular_contract') + ->join('park', 'regular_contract.park_id', '=', 'park.park_id') + ->where('contract_id', $contract_id) + ->where('user_id', $user_id) + ->where('park.management_id', $management_id) + ->first(); + + if (!$contract) { + // アクセス権限がない場合、エラーログで記録 + \Log::error("[ERROR] " . now()->format('Y-m-d H:i:s') . " アクセス権限なし: user_id=" . $user_id . ", contract_id=" . $contract_id); + abort(403, 'アクセス権限がありません。'); + } + + // システム操作の追跡のため、アクセスを記録 + \Log::info("[INFO] " . now()->format('Y-m-d H:i:s') . " 領収書宛名入力画面にアクセス: user_id=" . $user_id . ", contract_id=" . $contract_id); return view('receipt.input', [ - 'user_name' => $user ? $user->user_name : '', // ユーザー名(ヘッダー用) - 'contract_id' => $contract_id + 'user_name' => $user_name, + 'contract_id' => $contract_id, + 'management_code' => $management_code, ]); } - // 領収書発行(入力内容の保存) - public function issue(Request $request, $contract_id) + /** + * 領収書の宛名入力内容を確認し、保存する。 + * + * @param Request $request リクエストオブジェクト + * @param string $management_code 運営元コード + * @param string $contract_id 契約ID + * @return mixed PDFダウンロードまたはリダイレクト + */ + public function issue(Request $request, string $management_code, string $contract_id): mixed { $user_id = session('user_id'); if (!$user_id) { + // 未認証アクセス(セッション切れ)を追跡するため、INFOログで記録 + \Log::info("[INFO] " . now()->format('Y-m-d H:i:s') . " 未認証ユーザーによるアクセス(セッション切れ): 領収書発行"); return redirect('/login'); } - $receipt_name = $request->input('receipt_name'); - $keisho = $request->input('keisho'); - - // 既存レコードチェック + // 既存レコードがある場合、再発行を促す $exists = DB::table('inv_publish')->where('contract_id', $contract_id)->exists(); if ($exists) { // エラー時はinput画面に戻し、メッセージ表示 - return redirect()->back()->withInput()->withErrors(['contract_id' => 'この契約の領収書は既に発行されています。契約履歴から再発行を行ってください。']); + \Log::info("[INFO] " . now()->format('Y-m-d H:i:s') . " 領収書発行済み: user_id=" . $user_id . ", contract_id=" . $contract_id); + return redirect()->back()->withInput()->withErrors(['contract_id' => __('messages.RECEIPT_E000001')]); } - // 4バイト文字(絵文字等)チェック + $receipt_name = trim($request->input('receipt_name') ?? ''); + $keisho = $request->input('keisho'); + + // 宛名必須チェック + if (empty($receipt_name)) { + return redirect()->back()->withInput()->withErrors(['contract_id' => str_replace('{0}', '宛名', __('messages.SYSCOMMON_E000001'))]); + } + + // 4バイト文字(絵文字等)を防ぐ if (preg_match('/[\xF0-\xF7][\x80-\xBF]{3}/', $receipt_name)) { - return redirect()->back()->withInput()->withErrors(['contract_id' => '宛名に絵文字などの特殊文字は使用できません。']); + return redirect()->back()->withInput()->withErrors(['contract_id' => str_replace('{0}', '宛名', __('messages.SYSCOMMON_E000046'))]); } // 文字数チェック if (mb_strlen($receipt_name) > 30) { - return redirect()->back()->withInput()->withErrors(['contract_id' => '宛名は30文字以内で入力してください。']); + return redirect()->back()->withInput()->withErrors(['contract_id' => str_replace(['{0}', '{1}'], ['宛名', '30'], __('messages.SYSCOMMON_E000011'))]); } // 敬称選択チェック if (empty($keisho)) { - return redirect()->back()->withInput()->withErrors(['contract_id' => '敬称を選択してください。']); + return redirect()->back()->withInput()->withErrors(['contract_id' => str_replace('{0}', '敬称', __('messages.SYSCOMMON_E000047'))]); } - // inv_publishテーブルに新規登録(insert) + // 領収書再発行を可能にするため、領収書発行履歴登録 $inv_name = $receipt_name . $keisho; $now = date('Y-m-d H:i:s'); $seq = DB::table('inv_publish')->max('seq') ?? 0; @@ -74,60 +120,113 @@ class ReceiptController extends Controller 'inv_name' => $inv_name, 'published_at' => date('Y-m-d'), 'type' => 0, - 'count' => 1, + 'count' => 0, 'created_at' => $now, 'updated_at' => null, ]); - // 完了後はdownloadメソッドを直接呼び出し(再発行フラグfalseで渡す) + // 領収書発行履歴の登録成功を記録 + \Log::info("[INFO] " . now()->format('Y-m-d H:i:s') . " 領収書発行履歴登録成功: user_id=" . $user_id . ", contract_id=" . $contract_id . ", seq=" . $seq); + + $management = session('management'); + + // 完了後はdownloadメソッドを直接呼び出し(初回発行のため再発行フラグはfalseで渡す) $is_reissue = false; - return $this->download($contract_id, $is_reissue); + return $this->download($management->management_code, $contract_id, $is_reissue); } - public function download($contract_id, $is_reissue = true) + /** + * 領収書PDFをダウンロードする。 + * 契約IDに基づきデータを取得し、PDFを生成してレスポンスとして返す。 + * + * @param string $management_code 運営元コード + * @param string $contract_id 契約ID + * @param bool $is_reissue 再発行フラグ(デフォルトtrue) + * @return mixed PDFダウンロードまたはリダイレクト + * @throws \Symfony\Component\HttpKernel\Exception\HttpException アクセス権限エラーまたはシステムエラー時 + */ + public function download(string $management_code, string $contract_id, bool $is_reissue = true): mixed { - // 必要なデータを取得 - $contract = DB::table('regular_contract')->where('contract_id', $contract_id)->first(); - $inv = DB::table('inv_publish')->where('contract_id', $contract_id)->first(); - $t_number = DB::table('inv_setting')->value('t_number'); - - // park_name取得(regular_contract.park_id=park.park_id) - $park_name = ''; - if ($contract && $contract->park_id) { - $park = DB::table('park')->where('park_id', $contract->park_id)->first(); - if ($park && $park->park_name) { - $park_name = $park->park_name; + try { + $user_id = session('user_id'); + if (!$user_id) { + // 未認証アクセス(セッション切れ)を追跡するため、INFOログで記録 + \Log::info("[INFO] " . now()->format('Y-m-d H:i:s') . " 未認証ユーザーによるアクセス(セッション切れ): 領収書ダウンロード"); + return redirect('/login'); } + $management = session('management'); + $management_id = $management->management_id; + + $contract_id = (int) $contract_id; + + // PDFに表示する契約情報を取得 + $contract = DB::table('regular_contract') + ->join('park', 'regular_contract.park_id', '=', 'park.park_id') + ->where('contract_id', $contract_id) + ->where('user_id', $user_id) + ->where('park.management_id', $management_id) + ->select('regular_contract.*', 'park.park_name') + ->first(); + + // PDFに表示する領収書名前を取得 + $inv = DB::table('inv_publish') + ->where('contract_id', $contract_id) + ->where('user_id', $user_id) + ->first(); + + // PDFに表示する事業者情報を取得 + $inv_setting = DB::table('inv_setting') + ->where('management_id', $management_id) + ->first(); + + // ダウンロード回数をカウントアップ + DB::table('inv_publish') + ->where('contract_id', $contract_id) + ->where('user_id', $user_id) + ->update([ + 'count' => DB::raw('count + 1'), + 'updated_at' => now(), + ]); + + // BladeテンプレートをHTMLにレンダリング + $html = view('receipt.pdf', [ + 'contract' => $contract, + 'inv' => $inv, + 'inv_setting' => $inv_setting, + 'is_reissue' => $is_reissue, + ])->render(); + + // mPDF最新版(autoload対応) + $mpdf = new \Mpdf\Mpdf([ + 'mode' => 'ja', + 'format' => 'A4', + 'custom_font_dir' => resource_path('fonts'), + 'custom_font_data' => [ + 'noto_sans_jp' => [ + 'R' => 'NotoSansJP-Regular.ttf', // 通常フォント + 'B' => 'NotoSansJP-Bold.ttf', // 太字フォント + ] + ], + 'default_font' => 'noto_sans_jp', + ]); + + $mpdf->WriteHTML($html); + + // システム操作の追跡のため、アクセスを記録 + if ($is_reissue) { + \Log::info("[INFO] " . now()->format('Y-m-d H:i:s') . " 領収書再発行ダウンロード実行: user_id=" . $user_id . ", contract_id=" . $contract_id); + } else { + \Log::info("[INFO] " . now()->format('Y-m-d H:i:s') . " 領収書新規発行ダウンロード実行: user_id=" . $user_id . ", contract_id=" . $contract_id); + } + + // PDFダウンロード + return response($mpdf->Output('receipt_' . $contract_id . '.pdf', 'S')) + ->header('Content-Type', 'application/pdf') + ->header('Content-Disposition', 'attachment; filename="receipt_' . $contract_id . '.pdf"'); + } catch (\Exception $e) { + // PDF生成エラーを記録 + \Log::error("[ERROR] " . now()->format('Y-m-d H:i:s') . " PDFダウンロードエラー: user_id=" . $user_id . ", contract_id=" . $contract_id . ", error=" . $e->getMessage()); + abort(500, '領収書ダウンロードに失敗しました。'); } - - // BladeテンプレートをHTMLにレンダリング - $html = view('receipt.pdf', [ - 'contract' => $contract, - 'inv' => $inv, - 't_number' => $t_number, - 'park_name' => $park_name, - 'is_reissue' => $is_reissue, - ])->render(); - - // mPDF最新版(autoload対応) - $mpdf = new \Mpdf\Mpdf([ - 'mode' => 'ja', - 'format' => 'A4', - 'custom_font_dir' => resource_path('fonts'), - 'custom_font_data' => [ - 'noto_sans_jp' => [ - 'R' => 'NotoSansJP-Regular.ttf', // 通常フォント - 'B' => 'NotoSansJP-Bold.ttf', // 太字フォント - ] - ], - 'default_font' => 'noto_sans_jp', - ]); - - $mpdf->WriteHTML($html); - - // PDFダウンロード - return response($mpdf->Output('receipt_' . $contract_id . '.pdf', 'S')) - ->header('Content-Type', 'application/pdf') - ->header('Content-Disposition', 'attachment; filename="receipt_' . $contract_id . '.pdf"'); } } diff --git a/app/Http/Controllers/RegularContractController.php b/app/Http/Controllers/RegularContractController.php index 259a80f..0cfe7ad 100644 --- a/app/Http/Controllers/RegularContractController.php +++ b/app/Http/Controllers/RegularContractController.php @@ -1,9 +1,13 @@ format('Y-m-d H:i:s') . " 未認証ユーザーによるアクセス(セッション切れ): 定期契約履歴確認画面アクセス"); + return redirect()->guest('/login'); } + // ヘッダー表示のためユーザー名取得 $user_name = DB::table('user')->where('user_id', $user_id)->value('user_name'); + // マルチテナント対応のため、運営元コード、IDを取得 + $management = session('management'); + $management_code = $management->management_code; + $management_id = $management->management_id; + // 定期契約情報を取得(ページネーション付き) $contracts_query = DB::table('regular_contract') ->join('park', 'regular_contract.park_id', '=', 'park.park_id') ->join('usertype', 'regular_contract.user_categoryid', '=', 'usertype.user_categoryid') - ->leftJoin('city', 'park.city_id', '=', 'city.city_id') ->where('regular_contract.user_id', $user_id) + ->where('park.management_id', $management_id) ->whereNotNull('regular_contract.contract_money') ->select( 'regular_contract.contract_id', 'park.park_name', 'usertype.usertype_subject1', + 'usertype.usertype_subject3', 'regular_contract.contract_periods', 'regular_contract.contract_periode', 'regular_contract.enable_months', 'regular_contract.park_id', - 'city.update_grace_period_start_date', + 'park.update_grace_period_start_date', + 'park.update_grace_period_end_date', ) ->orderBy('regular_contract.contract_id', 'desc'); // ページネーション(4件ずつ) $contracts = $contracts_query->paginate(4); - // grace日付加工 + // 日付をyyyy/MM/dd形式で画面表示するため加工 $contracts->getCollection()->transform(function ($contract) { $periode = $contract->contract_periode; $grace_day = $contract->update_grace_period_start_date; $ym = date('Y/m', strtotime($periode)); $day = str_pad($grace_day, 2, '0', STR_PAD_LEFT); $contract->periode_with_grace = $ym . '/' . $day; + $contract->formatted_periods = \Carbon\Carbon::parse($contract->contract_periods)->format('Y/m/d'); + $contract->has_receipt = DB::table('inv_publish')->where('contract_id', $contract->contract_id)->exists(); return $contract; }); - \Log::info('契約履歴表示画面にアクセス', [ - 'user_id' => $user_id, - ]); + // システム操作の追跡のため、アクセスを記録 + \Log::info("[INFO] " . now()->format('Y-m-d H:i:s') . " 契約履歴表示画面にアクセス: user_id=" . $user_id . ", management_code=" . $management_code); return view('regular_contract.history', [ 'active_menu' => 'SWC-6-1', // マイページメニューの選択状態用 'user_name' => $user_name, // ユーザー名(ヘッダー用) 'contracts' => $contracts, + 'management_code' => $management_code, ]); } diff --git a/app/Http/Middleware/ManagementMiddleware.php b/app/Http/Middleware/ManagementMiddleware.php index b15c07c..10ad397 100644 --- a/app/Http/Middleware/ManagementMiddleware.php +++ b/app/Http/Middleware/ManagementMiddleware.php @@ -7,6 +7,7 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; use Illuminate\Http\Response; +use Illuminate\Http\RedirectResponse; class ManagementMiddleware { @@ -19,7 +20,7 @@ class ManagementMiddleware * @return Response 次の処理のレスポンス * @throws \Symfony\Component\HttpKernel\Exception\HttpException 運営元コードが見つからない場合 */ - public function handle(Request $request, Closure $next): Response + public function handle(Request $request, Closure $next): Response|RedirectResponse { // マルチテナント対応のため、URLの最初のセグメントを運営元コードとして扱う $path = $request->getPathInfo(); // パス全体を取得 diff --git a/public/assets/css/mypage/app.css b/public/assets/css/mypage/app.css index aec1c51..efd07c0 100644 --- a/public/assets/css/mypage/app.css +++ b/public/assets/css/mypage/app.css @@ -12,24 +12,29 @@ -webkit-transform: rotate(0deg); transform: rotate(0deg); } + to { -webkit-transform: rotate(360deg); transform: rotate(360deg); } } + @keyframes jconfirm-spin { from { -webkit-transform: rotate(0deg); transform: rotate(0deg); } + to { -webkit-transform: rotate(360deg); transform: rotate(360deg); } } + body[class*="jconfirm-no-scroll-"] { overflow: hidden !important; } + .jconfirm { position: fixed; top: 0; @@ -40,6 +45,7 @@ body[class*="jconfirm-no-scroll-"] { font-family: inherit; overflow: hidden; } + .jconfirm .jconfirm-bg { position: fixed; top: 0; @@ -49,9 +55,11 @@ body[class*="jconfirm-no-scroll-"] { -webkit-transition: opacity 0.4s; transition: opacity 0.4s; } + .jconfirm .jconfirm-bg.jconfirm-bg-h { opacity: 0 !important; } + .jconfirm .jconfirm-scrollpane { -webkit-perspective: 500px; perspective: 500px; @@ -61,28 +69,34 @@ body[class*="jconfirm-no-scroll-"] { width: 100%; height: 100%; } + .jconfirm .jconfirm-row { display: table-row; width: 100%; } + .jconfirm .jconfirm-cell { display: table-cell; vertical-align: middle; } + .jconfirm .jconfirm-holder { max-height: 100%; padding: 50px 0; } + .jconfirm .jconfirm-box-container { -webkit-transition: -webkit-transform; transition: -webkit-transform; transition: transform; transition: transform, -webkit-transform; } + .jconfirm .jconfirm-box-container.jconfirm-no-transition { -webkit-transition: none !important; transition: none !important; } + .jconfirm .jconfirm-box { background: white; border-radius: 4px; @@ -93,153 +107,198 @@ body[class*="jconfirm-no-scroll-"] { margin-left: auto; margin-right: auto; } + @-webkit-keyframes type-blue { + 1%, 100% { border-color: #3498db; } + 50% { border-color: #5faee3; } } + @keyframes type-blue { + 1%, 100% { border-color: #3498db; } + 50% { border-color: #5faee3; } } + @-webkit-keyframes type-green { + 1%, 100% { border-color: #2ecc71; } + 50% { border-color: #54d98c; } } + @keyframes type-green { + 1%, 100% { border-color: #2ecc71; } + 50% { border-color: #54d98c; } } + @-webkit-keyframes type-red { + 1%, 100% { border-color: #e74c3c; } + 50% { border-color: #ed7669; } } + @keyframes type-red { + 1%, 100% { border-color: #e74c3c; } + 50% { border-color: #ed7669; } } + @-webkit-keyframes type-orange { + 1%, 100% { border-color: #f1c40f; } + 50% { border-color: #f4d03f; } } + @keyframes type-orange { + 1%, 100% { border-color: #f1c40f; } + 50% { border-color: #f4d03f; } } + @-webkit-keyframes type-purple { + 1%, 100% { border-color: #9b59b6; } + 50% { border-color: #b07cc6; } } + @keyframes type-purple { + 1%, 100% { border-color: #9b59b6; } + 50% { border-color: #b07cc6; } } + @-webkit-keyframes type-dark { + 1%, 100% { border-color: #34495e; } + 50% { border-color: #46627f; } } + @keyframes type-dark { + 1%, 100% { border-color: #34495e; } + 50% { border-color: #46627f; } } + .jconfirm .jconfirm-box.jconfirm-type-animated { -webkit-animation-duration: 2s; animation-duration: 2s; -webkit-animation-iteration-count: infinite; animation-iteration-count: infinite; } + .jconfirm .jconfirm-box.jconfirm-type-blue { border-top: solid 7px #3498db; -webkit-animation-name: type-blue; animation-name: type-blue; } + .jconfirm .jconfirm-box.jconfirm-type-green { border-top: solid 7px #2ecc71; -webkit-animation-name: type-green; animation-name: type-green; } + .jconfirm .jconfirm-box.jconfirm-type-red { border-top: solid 7px #e74c3c; -webkit-animation-name: type-red; animation-name: type-red; } + .jconfirm .jconfirm-box.jconfirm-type-orange { border-top: solid 7px #f1c40f; -webkit-animation-name: type-orange; animation-name: type-orange; } + .jconfirm .jconfirm-box.jconfirm-type-purple { border-top: solid 7px #9b59b6; -webkit-animation-name: type-purple; animation-name: type-purple; } + .jconfirm .jconfirm-box.jconfirm-type-dark { border-top: solid 7px #34495e; -webkit-animation-name: type-dark; animation-name: type-dark; } + .jconfirm .jconfirm-box.loading { height: 120px; } + .jconfirm .jconfirm-box.loading:before { content: ""; position: absolute; @@ -251,6 +310,7 @@ body[class*="jconfirm-no-scroll-"] { border-radius: 10px; z-index: 1; } + .jconfirm .jconfirm-box.loading:after { opacity: 0.6; content: ""; @@ -268,6 +328,7 @@ body[class*="jconfirm-no-scroll-"] { margin-top: -15px; z-index: 2; } + .jconfirm .jconfirm-box div.jconfirm-closeIcon { height: 20px; width: 20px; @@ -282,21 +343,27 @@ body[class*="jconfirm-no-scroll-"] { display: none; z-index: 1; } + .jconfirm .jconfirm-box div.jconfirm-closeIcon:empty { display: none; } + .jconfirm .jconfirm-box div.jconfirm-closeIcon .fa { font-size: 16px; } + .jconfirm .jconfirm-box div.jconfirm-closeIcon .glyphicon { font-size: 16px; } + .jconfirm .jconfirm-box div.jconfirm-closeIcon .zmdi { font-size: 16px; } + .jconfirm .jconfirm-box div.jconfirm-closeIcon:hover { opacity: 1; } + .jconfirm .jconfirm-box div.jconfirm-title-c { display: block; font-size: 22px; @@ -308,20 +375,25 @@ body[class*="jconfirm-no-scroll-"] { cursor: default; padding-bottom: 15px; } + .jconfirm .jconfirm-box div.jconfirm-title-c.jconfirm-hand { cursor: move; } + .jconfirm .jconfirm-box div.jconfirm-title-c .jconfirm-icon-c { font-size: inherit; display: inline-block; vertical-align: middle; } + .jconfirm .jconfirm-box div.jconfirm-title-c .jconfirm-icon-c i { vertical-align: middle; } + .jconfirm .jconfirm-box div.jconfirm-title-c .jconfirm-icon-c:empty { display: none; } + .jconfirm .jconfirm-box div.jconfirm-title-c .jconfirm-title { -webkit-user-select: none; -moz-user-select: none; @@ -332,9 +404,11 @@ body[class*="jconfirm-no-scroll-"] { display: inline-block; vertical-align: middle; } + .jconfirm .jconfirm-box div.jconfirm-title-c .jconfirm-title:empty { display: none; } + .jconfirm .jconfirm-box div.jconfirm-content-pane { margin-bottom: 15px; height: auto; @@ -346,37 +420,47 @@ body[class*="jconfirm-no-scroll-"] { overflow-x: hidden; overflow-y: auto; } + .jconfirm .jconfirm-box div.jconfirm-content-pane.no-scroll { overflow-y: hidden; } + .jconfirm .jconfirm-box div.jconfirm-content-pane::-webkit-scrollbar { width: 3px; } + .jconfirm .jconfirm-box div.jconfirm-content-pane::-webkit-scrollbar-track { background: rgba(0, 0, 0, 0.1); } + .jconfirm .jconfirm-box div.jconfirm-content-pane::-webkit-scrollbar-thumb { background: #666; border-radius: 3px; } + .jconfirm .jconfirm-box div.jconfirm-content-pane .jconfirm-content { overflow: auto; } + .jconfirm .jconfirm-box div.jconfirm-content-pane .jconfirm-content img { max-width: 100%; height: auto; } + .jconfirm .jconfirm-box div.jconfirm-content-pane .jconfirm-content:empty { display: none; } + .jconfirm .jconfirm-box .jconfirm-buttons { padding-bottom: 11px; } -.jconfirm .jconfirm-box .jconfirm-buttons > button { + +.jconfirm .jconfirm-box .jconfirm-buttons>button { margin-bottom: 4px; margin-left: 2px; margin-right: 2px; } + .jconfirm .jconfirm-box .jconfirm-buttons button { display: inline-block; padding: 6px 12px; @@ -407,6 +491,7 @@ body[class*="jconfirm-no-scroll-"] { border: none; background-image: none; } + .jconfirm .jconfirm-box .jconfirm-buttons button.btn-blue { background-color: #3498db; color: #fff; @@ -414,10 +499,12 @@ body[class*="jconfirm-no-scroll-"] { -webkit-transition: background 0.2s; transition: background 0.2s; } + .jconfirm .jconfirm-box .jconfirm-buttons button.btn-blue:hover { background-color: #2980b9; color: #fff; } + .jconfirm .jconfirm-box .jconfirm-buttons button.btn-green { background-color: #2ecc71; color: #fff; @@ -425,10 +512,12 @@ body[class*="jconfirm-no-scroll-"] { -webkit-transition: background 0.2s; transition: background 0.2s; } + .jconfirm .jconfirm-box .jconfirm-buttons button.btn-green:hover { background-color: #27ae60; color: #fff; } + .jconfirm .jconfirm-box .jconfirm-buttons button.btn-red { background-color: #e74c3c; color: #fff; @@ -436,10 +525,12 @@ body[class*="jconfirm-no-scroll-"] { -webkit-transition: background 0.2s; transition: background 0.2s; } + .jconfirm .jconfirm-box .jconfirm-buttons button.btn-red:hover { background-color: #c0392b; color: #fff; } + .jconfirm .jconfirm-box .jconfirm-buttons button.btn-orange { background-color: #f1c40f; color: #fff; @@ -447,10 +538,12 @@ body[class*="jconfirm-no-scroll-"] { -webkit-transition: background 0.2s; transition: background 0.2s; } + .jconfirm .jconfirm-box .jconfirm-buttons button.btn-orange:hover { background-color: #f39c12; color: #fff; } + .jconfirm .jconfirm-box .jconfirm-buttons button.btn-default { background-color: #ecf0f1; color: #000; @@ -458,10 +551,12 @@ body[class*="jconfirm-no-scroll-"] { -webkit-transition: background 0.2s; transition: background 0.2s; } + .jconfirm .jconfirm-box .jconfirm-buttons button.btn-default:hover { background-color: #bdc3c7; color: #000; } + .jconfirm .jconfirm-box .jconfirm-buttons button.btn-purple { background-color: #9b59b6; color: #fff; @@ -469,10 +564,12 @@ body[class*="jconfirm-no-scroll-"] { -webkit-transition: background 0.2s; transition: background 0.2s; } + .jconfirm .jconfirm-box .jconfirm-buttons button.btn-purple:hover { background-color: #8e44ad; color: #fff; } + .jconfirm .jconfirm-box .jconfirm-buttons button.btn-dark { background-color: #34495e; color: #fff; @@ -480,64 +577,73 @@ body[class*="jconfirm-no-scroll-"] { -webkit-transition: background 0.2s; transition: background 0.2s; } + .jconfirm .jconfirm-box .jconfirm-buttons button.btn-dark:hover { background-color: #2c3e50; color: #fff; } + .jconfirm .jconfirm-box.jconfirm-type-red .jconfirm-title-c .jconfirm-icon-c { color: #e74c3c !important; } + .jconfirm .jconfirm-box.jconfirm-type-blue .jconfirm-title-c .jconfirm-icon-c { color: #3498db !important; } + .jconfirm .jconfirm-box.jconfirm-type-green .jconfirm-title-c .jconfirm-icon-c { color: #2ecc71 !important; } -.jconfirm - .jconfirm-box.jconfirm-type-purple - .jconfirm-title-c - .jconfirm-icon-c { + +.jconfirm .jconfirm-box.jconfirm-type-purple .jconfirm-title-c .jconfirm-icon-c { color: #9b59b6 !important; } -.jconfirm - .jconfirm-box.jconfirm-type-orange - .jconfirm-title-c - .jconfirm-icon-c { + +.jconfirm .jconfirm-box.jconfirm-type-orange .jconfirm-title-c .jconfirm-icon-c { color: #f1c40f !important; } + .jconfirm .jconfirm-box.jconfirm-type-dark .jconfirm-title-c .jconfirm-icon-c { color: #34495e !important; } + .jconfirm .jconfirm-clear { clear: both; } + .jconfirm.jconfirm-rtl { direction: rtl; } + .jconfirm.jconfirm-rtl div.jconfirm-closeIcon { left: 5px; right: auto; } + .jconfirm.jconfirm-white .jconfirm-bg, .jconfirm.jconfirm-light .jconfirm-bg { background-color: #444; opacity: 0.2; } + .jconfirm.jconfirm-white .jconfirm-box, .jconfirm.jconfirm-light .jconfirm-box { -webkit-box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2); box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2); border-radius: 5px; } + .jconfirm.jconfirm-white .jconfirm-box .jconfirm-title-c .jconfirm-icon-c, .jconfirm.jconfirm-light .jconfirm-box .jconfirm-title-c .jconfirm-icon-c { margin-right: 8px; margin-left: 0px; } + .jconfirm.jconfirm-white .jconfirm-box .jconfirm-buttons, .jconfirm.jconfirm-light .jconfirm-box .jconfirm-buttons { float: right; } + .jconfirm.jconfirm-white .jconfirm-box .jconfirm-buttons button, .jconfirm.jconfirm-light .jconfirm-box .jconfirm-buttons button { text-transform: uppercase; @@ -545,32 +651,31 @@ body[class*="jconfirm-no-scroll-"] { font-weight: bold; text-shadow: none; } + .jconfirm.jconfirm-white .jconfirm-box .jconfirm-buttons button.btn-default, .jconfirm.jconfirm-light .jconfirm-box .jconfirm-buttons button.btn-default { -webkit-box-shadow: none; box-shadow: none; color: #333; } -.jconfirm.jconfirm-white - .jconfirm-box - .jconfirm-buttons - button.btn-default:hover, -.jconfirm.jconfirm-light - .jconfirm-box - .jconfirm-buttons - button.btn-default:hover { + +.jconfirm.jconfirm-white .jconfirm-box .jconfirm-buttons button.btn-default:hover, +.jconfirm.jconfirm-light .jconfirm-box .jconfirm-buttons button.btn-default:hover { background: #ddd; } + .jconfirm.jconfirm-white.jconfirm-rtl .jconfirm-title-c .jconfirm-icon-c, .jconfirm.jconfirm-light.jconfirm-rtl .jconfirm-title-c .jconfirm-icon-c { margin-left: 8px; margin-right: 0px; } + .jconfirm.jconfirm-black .jconfirm-bg, .jconfirm.jconfirm-dark .jconfirm-bg { background-color: darkslategray; opacity: 0.4; } + .jconfirm.jconfirm-black .jconfirm-box, .jconfirm.jconfirm-dark .jconfirm-box { -webkit-box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2); @@ -579,15 +684,18 @@ body[class*="jconfirm-no-scroll-"] { border-radius: 5px; color: white; } + .jconfirm.jconfirm-black .jconfirm-box .jconfirm-title-c .jconfirm-icon-c, .jconfirm.jconfirm-dark .jconfirm-box .jconfirm-title-c .jconfirm-icon-c { margin-right: 8px; margin-left: 0px; } + .jconfirm.jconfirm-black .jconfirm-box .jconfirm-buttons, .jconfirm.jconfirm-dark .jconfirm-box .jconfirm-buttons { float: right; } + .jconfirm.jconfirm-black .jconfirm-box .jconfirm-buttons button, .jconfirm.jconfirm-dark .jconfirm-box .jconfirm-buttons button { border: none; @@ -600,6 +708,7 @@ body[class*="jconfirm-no-scroll-"] { transition: background 0.1s; color: white; } + .jconfirm.jconfirm-black .jconfirm-box .jconfirm-buttons button.btn-default, .jconfirm.jconfirm-dark .jconfirm-box .jconfirm-buttons button.btn-default { -webkit-box-shadow: none; @@ -607,111 +716,128 @@ body[class*="jconfirm-no-scroll-"] { color: #fff; background: none; } -.jconfirm.jconfirm-black - .jconfirm-box - .jconfirm-buttons - button.btn-default:hover, -.jconfirm.jconfirm-dark - .jconfirm-box - .jconfirm-buttons - button.btn-default:hover { + +.jconfirm.jconfirm-black .jconfirm-box .jconfirm-buttons button.btn-default:hover, +.jconfirm.jconfirm-dark .jconfirm-box .jconfirm-buttons button.btn-default:hover { background: #666; } + .jconfirm.jconfirm-black.jconfirm-rtl .jconfirm-title-c .jconfirm-icon-c, .jconfirm.jconfirm-dark.jconfirm-rtl .jconfirm-title-c .jconfirm-icon-c { margin-left: 8px; margin-right: 0px; } + .jconfirm .jconfirm-box.hilight.jconfirm-hilight-shake { -webkit-animation: shake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both; animation: shake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both; -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } + .jconfirm .jconfirm-box.hilight.jconfirm-hilight-glow { -webkit-animation: glow 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both; animation: glow 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both; -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } + @-webkit-keyframes shake { + 10%, 90% { -webkit-transform: translate3d(-2px, 0, 0); transform: translate3d(-2px, 0, 0); } + 20%, 80% { -webkit-transform: translate3d(4px, 0, 0); transform: translate3d(4px, 0, 0); } + 30%, 50%, 70% { -webkit-transform: translate3d(-8px, 0, 0); transform: translate3d(-8px, 0, 0); } + 40%, 60% { -webkit-transform: translate3d(8px, 0, 0); transform: translate3d(8px, 0, 0); } } + @keyframes shake { + 10%, 90% { -webkit-transform: translate3d(-2px, 0, 0); transform: translate3d(-2px, 0, 0); } + 20%, 80% { -webkit-transform: translate3d(4px, 0, 0); transform: translate3d(4px, 0, 0); } + 30%, 50%, 70% { -webkit-transform: translate3d(-8px, 0, 0); transform: translate3d(-8px, 0, 0); } + 40%, 60% { -webkit-transform: translate3d(8px, 0, 0); transform: translate3d(8px, 0, 0); } } + @-webkit-keyframes glow { + 0%, 100% { -webkit-box-shadow: 0 0 0px red; box-shadow: 0 0 0px red; } + 50% { -webkit-box-shadow: 0 0 30px red; box-shadow: 0 0 30px red; } } + @keyframes glow { + 0%, 100% { -webkit-box-shadow: 0 0 0px red; box-shadow: 0 0 0px red; } + 50% { -webkit-box-shadow: 0 0 30px red; box-shadow: 0 0 30px red; } } + /*Transition rules*/ .jconfirm { -webkit-perspective: 400px; perspective: 400px; } + .jconfirm .jconfirm-box { opacity: 1; -webkit-transition-property: all; transition-property: all; } + .jconfirm .jconfirm-box.jconfirm-animation-top, .jconfirm .jconfirm-box.jconfirm-animation-left, .jconfirm .jconfirm-box.jconfirm-animation-right, @@ -727,126 +853,153 @@ body[class*="jconfirm-no-scroll-"] { .jconfirm .jconfirm-box.jconfirm-animation-scalex { opacity: 0; } + .jconfirm .jconfirm-box.jconfirm-animation-rotate { -webkit-transform: rotate(90deg); transform: rotate(90deg); } + .jconfirm .jconfirm-box.jconfirm-animation-rotatex { -webkit-transform: rotateX(90deg); transform: rotateX(90deg); -webkit-transform-origin: center; transform-origin: center; } + .jconfirm .jconfirm-box.jconfirm-animation-rotatexr { -webkit-transform: rotateX(-90deg); transform: rotateX(-90deg); -webkit-transform-origin: center; transform-origin: center; } + .jconfirm .jconfirm-box.jconfirm-animation-rotatey { -webkit-transform: rotatey(90deg); transform: rotatey(90deg); -webkit-transform-origin: center; transform-origin: center; } + .jconfirm .jconfirm-box.jconfirm-animation-rotateyr { -webkit-transform: rotatey(-90deg); transform: rotatey(-90deg); -webkit-transform-origin: center; transform-origin: center; } + .jconfirm .jconfirm-box.jconfirm-animation-scaley { -webkit-transform: scaley(1.5); transform: scaley(1.5); -webkit-transform-origin: center; transform-origin: center; } + .jconfirm .jconfirm-box.jconfirm-animation-scalex { -webkit-transform: scalex(1.5); transform: scalex(1.5); -webkit-transform-origin: center; transform-origin: center; } + .jconfirm .jconfirm-box.jconfirm-animation-top { -webkit-transform: translate(0px, -100px); transform: translate(0px, -100px); } + .jconfirm .jconfirm-box.jconfirm-animation-left { -webkit-transform: translate(-100px, 0px); transform: translate(-100px, 0px); } + .jconfirm .jconfirm-box.jconfirm-animation-right { -webkit-transform: translate(100px, 0px); transform: translate(100px, 0px); } + .jconfirm .jconfirm-box.jconfirm-animation-bottom { -webkit-transform: translate(0px, 100px); transform: translate(0px, 100px); } + .jconfirm .jconfirm-box.jconfirm-animation-zoom { -webkit-transform: scale(1.2); transform: scale(1.2); } + .jconfirm .jconfirm-box.jconfirm-animation-scale { -webkit-transform: scale(0.5); transform: scale(0.5); } + .jconfirm .jconfirm-box.jconfirm-animation-none { visibility: hidden; } + .jconfirm.jconfirm-supervan .jconfirm-bg { background-color: rgba(54, 70, 93, 0.95); } + .jconfirm.jconfirm-supervan .jconfirm-box { background-color: transparent; } + .jconfirm.jconfirm-supervan .jconfirm-box.jconfirm-type-blue { border: none; } + .jconfirm.jconfirm-supervan .jconfirm-box.jconfirm-type-green { border: none; } + .jconfirm.jconfirm-supervan .jconfirm-box.jconfirm-type-red { border: none; } + .jconfirm.jconfirm-supervan .jconfirm-box.jconfirm-type-orange { border: none; } + .jconfirm.jconfirm-supervan .jconfirm-box.jconfirm-type-purple { border: none; } + .jconfirm.jconfirm-supervan .jconfirm-box.jconfirm-type-dark { border: none; } + .jconfirm.jconfirm-supervan .jconfirm-box div.jconfirm-closeIcon { color: white; } + .jconfirm.jconfirm-supervan .jconfirm-box div.jconfirm-title-c { text-align: center; color: white; font-size: 28px; font-weight: normal; } -.jconfirm.jconfirm-supervan .jconfirm-box div.jconfirm-title-c > * { + +.jconfirm.jconfirm-supervan .jconfirm-box div.jconfirm-title-c>* { padding-bottom: 25px; } -.jconfirm.jconfirm-supervan - .jconfirm-box - div.jconfirm-title-c - .jconfirm-icon-c { + +.jconfirm.jconfirm-supervan .jconfirm-box div.jconfirm-title-c .jconfirm-icon-c { margin-right: 8px; margin-left: 0px; } + .jconfirm.jconfirm-supervan .jconfirm-box div.jconfirm-content-pane { margin-bottom: 25px; } + .jconfirm.jconfirm-supervan .jconfirm-box div.jconfirm-content { text-align: center; color: white; } + .jconfirm.jconfirm-supervan .jconfirm-box .jconfirm-buttons { text-align: center; } + .jconfirm.jconfirm-supervan .jconfirm-box .jconfirm-buttons button { font-size: 16px; border-radius: 2px; @@ -857,16 +1010,16 @@ body[class*="jconfirm-no-scroll-"] { padding: 10px; min-width: 100px; } -.jconfirm.jconfirm-supervan.jconfirm-rtl - .jconfirm-box - div.jconfirm-title-c - .jconfirm-icon-c { + +.jconfirm.jconfirm-supervan.jconfirm-rtl .jconfirm-box div.jconfirm-title-c .jconfirm-icon-c { margin-left: 8px; margin-right: 0px; } + .jconfirm.jconfirm-material .jconfirm-bg { background-color: rgba(0, 0, 0, 0.67); } + .jconfirm.jconfirm-material .jconfirm-box { background-color: white; -webkit-box-shadow: 0 7px 8px -4px rgba(0, 0, 0, 0.2), @@ -875,35 +1028,44 @@ body[class*="jconfirm-no-scroll-"] { 0 13px 19px 2px rgba(0, 0, 0, 0.14), 0 5px 24px 4px rgba(0, 0, 0, 0.12); padding: 30px 25px 10px 25px; } + .jconfirm.jconfirm-material .jconfirm-box .jconfirm-title-c .jconfirm-icon-c { margin-right: 8px; margin-left: 0px; } + .jconfirm.jconfirm-material .jconfirm-box div.jconfirm-closeIcon { color: rgba(0, 0, 0, 0.87); } + .jconfirm.jconfirm-material .jconfirm-box div.jconfirm-title-c { color: rgba(0, 0, 0, 0.87); font-size: 22px; font-weight: bold; } + .jconfirm.jconfirm-material .jconfirm-box div.jconfirm-content { color: rgba(0, 0, 0, 0.87); } + .jconfirm.jconfirm-material .jconfirm-box .jconfirm-buttons { text-align: right; } + .jconfirm.jconfirm-material .jconfirm-box .jconfirm-buttons button { text-transform: uppercase; font-weight: 500; } + .jconfirm.jconfirm-material.jconfirm-rtl .jconfirm-title-c .jconfirm-icon-c { margin-left: 8px; margin-right: 0px; } + .jconfirm.jconfirm-bootstrap .jconfirm-bg { background-color: rgba(0, 0, 0, 0.21); } + .jconfirm.jconfirm-bootstrap .jconfirm-box { background-color: white; -webkit-box-shadow: 0 3px 8px 0px rgba(0, 0, 0, 0.2); @@ -911,13 +1073,16 @@ body[class*="jconfirm-no-scroll-"] { border: solid 1px rgba(0, 0, 0, 0.4); padding: 15px 0 0; } + .jconfirm.jconfirm-bootstrap .jconfirm-box .jconfirm-title-c .jconfirm-icon-c { margin-right: 8px; margin-left: 0px; } + .jconfirm.jconfirm-bootstrap .jconfirm-box div.jconfirm-closeIcon { color: rgba(0, 0, 0, 0.87); } + .jconfirm.jconfirm-bootstrap .jconfirm-box div.jconfirm-title-c { color: rgba(0, 0, 0, 0.87); font-size: 22px; @@ -925,10 +1090,12 @@ body[class*="jconfirm-no-scroll-"] { padding-left: 15px; padding-right: 15px; } + .jconfirm.jconfirm-bootstrap .jconfirm-box div.jconfirm-content { color: rgba(0, 0, 0, 0.87); padding: 0px 15px; } + .jconfirm.jconfirm-bootstrap .jconfirm-box .jconfirm-buttons { text-align: right; padding: 10px; @@ -937,17 +1104,21 @@ body[class*="jconfirm-no-scroll-"] { overflow: hidden; border-radius: 0 0 4px 4px; } + .jconfirm.jconfirm-bootstrap .jconfirm-box .jconfirm-buttons button { font-weight: 500; } + .jconfirm.jconfirm-bootstrap.jconfirm-rtl .jconfirm-title-c .jconfirm-icon-c { margin-left: 8px; margin-right: 0px; } + .jconfirm.jconfirm-modern .jconfirm-bg { background-color: slategray; opacity: 0.6; } + .jconfirm.jconfirm-modern .jconfirm-box { background-color: white; -webkit-box-shadow: 0 7px 8px -4px rgba(0, 0, 0, 0.2), @@ -956,11 +1127,13 @@ body[class*="jconfirm-no-scroll-"] { 0 13px 19px 2px rgba(0, 0, 0, 0.14), 0 5px 24px 4px rgba(0, 0, 0, 0.12); padding: 30px 30px 15px; } + .jconfirm.jconfirm-modern .jconfirm-box div.jconfirm-closeIcon { color: rgba(0, 0, 0, 0.87); top: 15px; right: 15px; } + .jconfirm.jconfirm-modern .jconfirm-box div.jconfirm-title-c { color: rgba(0, 0, 0, 0.87); font-size: 24px; @@ -968,6 +1141,7 @@ body[class*="jconfirm-no-scroll-"] { text-align: center; margin-bottom: 10px; } + .jconfirm.jconfirm-modern .jconfirm-box div.jconfirm-title-c .jconfirm-icon-c { -webkit-transition: -webkit-transform 0.5s; transition: -webkit-transform 0.5s; @@ -982,15 +1156,18 @@ body[class*="jconfirm-no-scroll-"] { font-size: 69px; color: #aaa; } + .jconfirm.jconfirm-modern .jconfirm-box div.jconfirm-content { text-align: center; font-size: 15px; color: #777; margin-bottom: 25px; } + .jconfirm.jconfirm-modern .jconfirm-box .jconfirm-buttons { text-align: center; } + .jconfirm.jconfirm-modern .jconfirm-box .jconfirm-buttons button { font-weight: bold; text-transform: uppercase; @@ -998,16 +1175,16 @@ body[class*="jconfirm-no-scroll-"] { transition: background 0.1s; padding: 10px 20px; } -.jconfirm.jconfirm-modern .jconfirm-box .jconfirm-buttons button + button { + +.jconfirm.jconfirm-modern .jconfirm-box .jconfirm-buttons button+button { margin-left: 4px; } -.jconfirm.jconfirm-modern.jconfirm-open - .jconfirm-box - .jconfirm-title-c - .jconfirm-icon-c { + +.jconfirm.jconfirm-modern.jconfirm-open .jconfirm-box .jconfirm-title-c .jconfirm-icon-c { -webkit-transform: scale(1); transform: scale(1); } + .login { margin-top: 95px; } @@ -1307,10 +1484,7 @@ a.btn_filter { border-radius: 0.5rem; } -.searchUserSeqGroup - .select2-container - .select2-selection--single - .select2-selection__rendered { +.searchUserSeqGroup .select2-container .select2-selection--single .select2-selection__rendered { font-family: inherit; font-size: 1.25rem; color: #808080 !important; @@ -1341,10 +1515,7 @@ a.btn_filter { padding: 0; } -.searchUserSeqGroup - .select2-container--default - .select2-selection--single - .select2-selection__arrow { +.searchUserSeqGroup .select2-container--default .select2-selection--single .select2-selection__arrow { height: 100%; top: -2px; } @@ -1368,7 +1539,308 @@ a.btn_filter { .font-size-1_25 { font-size: 1.25rem; } + .text-danger-bold { color: #dc3545 !important; font-weight: bold; +} + +.info-form { + max-width: 780px; + margin: 0 auto; + padding-left: 10px; +} + +.info-row { + display: flex; + align-items: flex-start; + margin-bottom: 1.2em; + flex-wrap: wrap; +} + +.info-label { + font-weight: bold; + color: #1abc9c; + font-size: 1.08em; + width: 180px; + min-width: 180px; + margin-right: 1.2em; + margin-bottom: 0; + text-align: left; + letter-spacing: 0.02em; +} + +.info-value { + font-size: 1.08em; + color: #222; + background: #f8f9fa; + border-radius: 10px; + padding: 0.7em 1.2em; + font-weight: 500; + word-break: break-all; + flex: 1; + min-width: 120px; +} + +.info-input { + font-size: 1.08em; + color: #222; + background: #fff; + border-radius: 10px; + padding: 0.7em 1.2em; + font-weight: 500; + border: 1px solid #a7a7a7; + flex: 1; + min-width: 120px; + box-sizing: border-box; + width: 100%; +} + +.info-input[readonly], +.info-input[disabled], +.info-input:disabled, +.info-input-disabled { + background: #eee !important; + color: #595959 !important; + border: 1px solid #ccc !important; + -webkit-text-fill-color: #595959 !important; + opacity: 1 !important; +} + +.info-img { + max-width: 110px; + border-radius: 10px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); + background: #f8f9fa; + padding: 0.5em; + margin-bottom: 0.2em; +} + +.info-row .form-check { + position: relative; + margin-right: 1rem; + display: inline-block; + vertical-align: middle; +} + +.info-row .form-check-label { + cursor: pointer; + color: #222; + font-weight: 500; + user-select: none; +} + +.green-btn { + background: #1abc9c; + color: #fff !important; + border: none; + box-shadow: 0 2px 8px rgba(26, 188, 156, 0.10); + font-size: 1.15em; + font-weight: bold; + border-radius: 12px; + padding: 0.8em 2.2em; + transition: background 0.2s, box-shadow 0.2s; +} + +.green-btn:hover, +.green-btn:focus { + background: #17a689; + color: #fff !important; +} + +.white-btn { + background: #fff; + color: #1abc9c !important; + border: 2px solid #1abc9c; + box-shadow: none; + font-size: 1.15em; + font-weight: bold; + border-radius: 12px; + padding: 0.8em 2.2em; + transition: background 0.2s, box-shadow 0.2s; +} + +.white-btn:hover, +.white-btn:focus { + background: #e8fcf6; + color: #1abc9c !important; + border-color: #1abc9c; +} + +.green-btn, +.white-btn { + text-align: center; + cursor: pointer; + display: inline-block; + text-decoration: none !important; + user-select: none; +} + +.green-btn:active, +.white-btn:active { + opacity: 0.85; +} + +.green-btn[disabled], +.white-btn[disabled], +.green-btn.disabled, +.white-btn.disabled { + background: #ccc !important; + color: #fff !important; + border: 1px solid #bbb !important; + cursor: not-allowed !important; + pointer-events: none !important; + opacity: 0.7; +} + +.green-btn[disabled]:hover, +.white-btn[disabled]:hover, +.green-btn.disabled:hover, +.white-btn.disabled:hover { + background: #ccc !important; + color: #fff !important; + border: 1px solid #bbb !important; +} + +.long-btn { + display: block; + width: 100%; + margin: 0 auto 1em auto; +} + +.btn-row { + display: flex; + gap: 0.6rem; + align-items: stretch; + flex-wrap: nowrap; +} + +.btn-row .long-btn { + flex: 1 1 0; + width: auto; + margin: 0; + box-sizing: border-box; +} + +.title-header { + background: #e8fcf6; + padding: 1.2em 1em 1em 5.8em; + margin-bottom: 1.5em; + box-shadow: 0 2px 8px rgba(26, 188, 156, 0.07); + font-weight: bold; + color: #1abc9c; + font-size: 1.25em; + position: relative; +} + +.title-header::before { + content: ''; + display: block; + position: absolute; + left: 5em; + top: 22%; + height: 60%; + width: 8px; + background: #1abc9c; + border-radius: 3px; +} + +.info-input::placeholder, +input::placeholder, +textarea::placeholder { + color: #d4d4d4 !important; + opacity: 1; +} + +/* ベンダープレフィックス(互換性確保) */ +.info-input::-webkit-input-placeholder, +input::-webkit-input-placeholder, +textarea::-webkit-input-placeholder { + color: #bdbdbd !important; + opacity: 1; +} + +.info-input::-moz-placeholder, +input::-moz-placeholder, +textarea::-moz-placeholder { + color: #bdbdbd !important; + opacity: 1; +} + +.info-input:-ms-input-placeholder, +input:-ms-input-placeholder, +textarea:-ms-input-placeholder { + color: #bdbdbd !important; + opacity: 1; +} + +.info-input:-moz-placeholder, +input:-moz-placeholder, +textarea:-moz-placeholder { + color: #bdbdbd !important; + opacity: 1; +} + +@media (max-width: 600px) { + .info-form { + padding-left: 0; + max-width: 100%; + } + + .info-row { + flex-direction: column; + align-items: flex-start; + } + + .info-label { + width: 100%; + min-width: 0; + margin-right: 0; + margin-bottom: 0.2em; + text-align: left; + } + + .info-value { + min-width: 0; + width: 100%; + padding: 0.5em 0.7em; + } + + .info-img { + max-width: 80px; + } + + .green-btn { + font-size: 1em; + padding: 0.6em 1.2em; + } + + .white-btn { + font-size: 1em; + padding: 0.6em 1.2em; + } + + .btn-row { + flex-direction: column; + gap: 0.6rem; + } + + .btn-row[data-reverse-mobile="true"] { + flex-direction: column-reverse; + } + + .btn-row .long-btn { + width: 100%; + } + + .title-header { + font-size: 1em; + padding: 0.8em 0.5em 0.7em 1em; + } + + .title-header::before { + left: 0.2em; + height: 60%; + width: 7px; + } } \ No newline at end of file diff --git a/resources/lang/ja/messages.php b/resources/lang/ja/messages.php new file mode 100644 index 0000000..1edc2ab --- /dev/null +++ b/resources/lang/ja/messages.php @@ -0,0 +1,69 @@ + '必須項目:{0}を入力してください。', + 'SYSCOMMON_E000002' => '{0}はyyyy/MM/ddで入力してください。', + 'SYSCOMMON_E000003' => '{0}は半角文字で入力してください。', + 'SYSCOMMON_E000004' => '{0}は半角数字で入力してください。', + 'SYSCOMMON_E000005' => '{0}は半角英字で入力してください。', + 'SYSCOMMON_E000006' => '{0}は半角英数で入力してください。', + 'SYSCOMMON_E000007' => '{0}は半角カナで入力してください。', + 'SYSCOMMON_E000008' => '{0}は全角文字で入力してください。', + 'SYSCOMMON_E000009' => '{0}は{1}桁で入力してください。', + 'SYSCOMMON_E000010' => '{0}は{1}桁以内で入力してください。', + 'SYSCOMMON_E000011' => '{0}は{1}文字以内で入力してください。', + 'SYSCOMMON_E000012' => '{0}は0または0.0以外の文字を入力してください。', + 'SYSCOMMON_E000013' => '{0}にはアルファベットと数字だけが入力可能です。', + 'SYSCOMMON_E000014' => '{0}は整数部の最大桁数が{1}桁を超えています。', + 'SYSCOMMON_E000015' => '{0}は小数部の最大桁数が{1}桁を超えています。', + 'SYSCOMMON_E000016' => '{0}は整数部の最小桁数が{1}桁未満です。', + 'SYSCOMMON_E000017' => '{0}は小数部の最小桁数が{1}桁未満です。', + 'SYSCOMMON_E000018' => '{0}には正の値を入力してください。', + 'SYSCOMMON_E000019' => '{0}には負の値を入力してください。', + 'SYSCOMMON_E000020' => '{0}は整数{2}桁以内、小数{1}桁以内で入力してください。', + 'SYSCOMMON_E000021' => '{0}はマスタに存在しません。', + 'SYSCOMMON_E000022' => '{0}はマスタに既に存在しています。', + 'SYSCOMMON_E000023' => '{0}は既に削除されています。', + 'SYSCOMMON_E000024' => '一つ以上選択してください。', + 'SYSCOMMON_E000025' => '正しい区分を選択してください。', + 'SYSCOMMON_E000026' => '明細行を選択してください。', + 'SYSCOMMON_E000027' => '複数行の選択はできません。', + 'SYSCOMMON_E000028' => '{0}行以上の追加は行うことができません。', + 'SYSCOMMON_E000029' => '{0}行以上の挿入は行うことができません。', + 'SYSCOMMON_E000030' => '読取専用の為、行を削除することはできません。({0}行目)', + 'SYSCOMMON_E000031' => '{0}は編集できません。', + 'SYSCOMMON_E000032' => '明細行は{0}件以上入力してください。', + 'SYSCOMMON_E000033' => '検索条件を入力してください。', + 'SYSCOMMON_E000034' => '入力したIDまたはパスワードは正しくありません。', + 'SYSCOMMON_E000035' => '対象のデータは編集作業中に変更されました。再度編集画面を開き直してください。', + 'SYSCOMMON_E000036' => '対象のデータは既に削除されています。', + 'SYSCOMMON_E000037' => '関連データが存在するため修正、削除できません。', + 'SYSCOMMON_E000038' => '指定されたURLは存在しません。', + 'SYSCOMMON_E000039' => 'リクエストした画面は現在使用できません。', + 'SYSCOMMON_E000040' => '不正な画面遷移が行われました。メニュー選択から操作をやり直してください。', + 'SYSCOMMON_E000041' => 'システムエラーが発生しました。システム管理者に連絡してください。', + 'SYSCOMMON_E000042' => 'ファイルダウンロードに失敗しました。', + 'SYSCOMMON_E000043' => 'ファイルアップロードに失敗しました。', + 'SYSCOMMON_E000044' => 'バッチ処理が異常終了しました。', + 'SYSCOMMON_E000045' => '{0}は{1}のため、入力することができません。', + 'SYSCOMMON_E000046' => '{0}に特殊文字は使用できません。', + 'SYSCOMMON_E000047' => '{0}を選択してください。', + + // 汎用情報メッセージ + 'SYSCOMMON_I000001' => '登録します。よろしいですか?', + 'SYSCOMMON_I000002' => '更新します。よろしいですか?', + 'SYSCOMMON_I000003' => '削除します。よろしいですか?', + 'SYSCOMMON_I000004' => '一時保存します。よろしいですか?', + 'SYSCOMMON_I000005' => 'ログアウトしてよろしいですか?', + 'SYSCOMMON_I000006' => '入力内容が破棄されます。よろしいですか?', + 'SYSCOMMON_I000007' => 'ダウンロードします。よろしいですか?', + 'SYSCOMMON_I000008' => 'アップロードします。よろしいですか?', + 'SYSCOMMON_I000009' => '登録されました。{0}', + 'SYSCOMMON_I000010' => '更新されました。{0}', + 'SYSCOMMON_I000011' => '削除されました。{0}', + 'SYSCOMMON_I000012' => 'ダウンロードが終了しました。', + 'SYSCOMMON_I000013' => 'アップロードが終了しました。', + + // 領収書関連メッセージ + 'RECEIPT_E000001' => 'この契約の領収書は既に発行されています。契約履歴から再発行を行ってください。', +]; diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index ef41f01..28abea9 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -39,10 +39,6 @@
@yield('content')
- {{-- フッターメニュー --}} - @include('partials.mypagefootermenu') - {{-- ニュース --}} - @include('partials.news') {{-- フッター --}} @include('partials.footer') diff --git a/resources/views/receipt/input.blade.php b/resources/views/receipt/input.blade.php index 26e3334..f4e9848 100644 --- a/resources/views/receipt/input.blade.php +++ b/resources/views/receipt/input.blade.php @@ -1,35 +1,42 @@ @extends('layouts.app') +@section('title', '領収書の発行 | So-Manager') @section('content')
-
-

領収書の発行

-
+
領収書の発行
@if($errors->has('contract_id')) -
- {{ $errors->first('contract_id') }} -
+
+ {{ $errors->first('contract_id') }} +
@endif -
+ @csrf

領収書内容の入力

領収書の宛名を入力してください。

- +
- +
- +
- +
-
+ @endsection \ No newline at end of file diff --git a/resources/views/receipt/pdf.blade.php b/resources/views/receipt/pdf.blade.php index 6421e93..960fda3 100644 --- a/resources/views/receipt/pdf.blade.php +++ b/resources/views/receipt/pdf.blade.php @@ -58,12 +58,18 @@ font-size: 12px; } - .reissue { - position: absolute; - top: 16px; - left: 16px; - width: 100px; - height: 40px; + .reissue-label { + display: inline-block; + border: 2px solid #222; + border-radius: 36px; + padding: 14px 48px; + font-weight: bold; + font-size: 1.6em; + color: #222; + background: #fff; + letter-spacing: 0.05em; + box-sizing: border-box; + margin: 12px 0 0 0; } @@ -71,19 +77,19 @@
@if($is_reissue) - 再発行 + 再発行 @endif
No. {{ $inv->seq ?? '' }}
発行日: {{ !empty($inv->published_at) ? \Carbon\Carbon::parse($inv->published_at)->format('Y年m月d日') : '' }}
-
領収証
+
領収書
ID: {{ $contract->contract_id ?? '' }}
{{ $inv->inv_name ?? '' }}
- + @@ -107,23 +113,40 @@ {{ !empty($contract->contract_periods) ? \Carbon\Carbon::parse($contract->contract_periods)->format('Y年m月d日') : '' }} ~ {{ !empty($contract->contract_periode) ? \Carbon\Carbon::parse($contract->contract_periode)->format('Y年m月d日') : '' }} - )として
- 上記金額を正に領収いたしました。 + )として
+ {{ !empty($contract->contract_payment_day) ? \Carbon\Carbon::parse($contract->contract_payment_day)->format('Y年m月d日') : '' }}に上記金額を正に領収いたしました。
契約駐輪場名{{ $park_name ?? '' }}{{ $contract->park_name ?? '' }}
小計(10%対象)
- + @php + $stamp_file = null; + $extensions = ['png', 'jpeg', 'jpg']; + foreach ($extensions as $ext) { + $file_path = public_path('images/' . $inv_setting->t_name . '_stamp.' . $ext); + if (file_exists($file_path)) { + $stamp_file = $inv_setting->t_name . '_stamp.' . $ext; + break; + } + } + @endphp + @if($stamp_file) + + @endif
- 株式会社ソーリン
- 〒121-0073
- 東京都足立区六町四丁目12-25
- 適格事業者番号:{{ $t_number }}
- TEL:03-5856-4647
- FAX:03-5856-4648
+ {{ $inv_setting->t_name ?? '' }}
+ {{ $inv_setting->zipcode ?? '' }}
+ {{ $inv_setting->adrs ?? '' }}
+ 適格事業者番号:{{ $inv_setting->t_number ?? '' }}
+ @if(!empty($inv_setting->tel_num)) + TEL:{{ $inv_setting->tel_num}}
+ @endif + @if(!empty($inv_setting->fax_num)) + FAX:{{ $inv_setting->fax_num}}
+ @endif
diff --git a/resources/views/regular_contract/history.blade.php b/resources/views/regular_contract/history.blade.php index d86d8d1..d36cca4 100644 --- a/resources/views/regular_contract/history.blade.php +++ b/resources/views/regular_contract/history.blade.php @@ -1,9 +1,8 @@ @extends('layouts.app') +@section('title', '定期契約履歴を見る-契約履歴 | So-Manager') @section('content')
-
-

契約履歴 > 定期契約履歴を見る

-
+
契約履歴 > 定期契約履歴を見る
@if(count($contracts) > 0) @foreach($contracts as $i => $contract) @@ -23,11 +22,15 @@ 利用者区分 - {{ $contract->usertype_subject1 }} + {{ $contract->usertype_subject1 }} + @if($contract->usertype_subject3 !== '該当なし') + ・{{ $contract->usertype_subject3 }} + @endif + 開始日 - {{ \Carbon\Carbon::parse($contract->contract_periods)->format('Y/m/d') }} + {{ $contract->formatted_periods }} 月数 @@ -39,13 +42,10 @@ - @php - $has_receipt = DB::table('inv_publish')->where('contract_id', $contract->contract_id)->exists(); - @endphp - @if($has_receipt) - 領収書再発行 + @if($contract->has_receipt) + 領収書再発行 @else - 領収書発行 + 領収書発行 @endif @@ -64,11 +64,9 @@

定期契約情報はありません。

@endif -
- -
+
@@ -83,10 +81,20 @@ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04); } + .btn-outline-secondary.badge-pill.custom-rounded-btn:not([disabled]):hover, + .btn-outline-secondary.badge-pill.custom-rounded-btn:not(.disabled):hover { + color: #212529 !important; + } + .table.text-center { - border-radius: 0.25rem !important; + border-radius: 1.25rem !important; border-collapse: separate !important; overflow: hidden; } + + .card { + border-radius: 1.25rem !important; + overflow: hidden; + } \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 428c803..d512a69 100644 --- a/routes/web.php +++ b/routes/web.php @@ -103,7 +103,7 @@ Route::middleware([\App\Http\Middleware\ManagementMiddleware::class])->group(fun // 領収書発行 Route::get('/{management_code}/receipt/input/{contract_id}', [ReceiptController::class, 'input'])->name('receipt.input'); Route::get('/{management_code}/receipt/download/{contract_id}', [ReceiptController::class, 'download'])->name('receipt.download'); - Route::post('/{management_code}/receipt/issue/{contract_id}', [ReceiptController::class, 'issue']); + Route::post('/{management_code}/receipt/issue/{contract_id}', [ReceiptController::class, 'issue'])->name('receipt.issue'); // シール再発行 Route::get('/{management_code}/seal/reissue/{contract_id}', [SealReissueController::class, 'index'])->name('seal.reissue');