|
35 | 35 | // 月別明細の乗車料金(紙様式どおり) |
36 | 36 | $fare_rows = [680, 660, 640, 620, 610, 600, 590, 580, 570]; |
37 | 37 |
|
38 | | -// 請求対象の3か月(直近3か月をデフォルトで提案) |
39 | | -$default_months = []; |
40 | | -for ($i = 3; $i >= 1; $i--) { |
41 | | - $d = new DateTime(); |
42 | | - $d->modify("-{$i} month"); |
43 | | - $default_months[] = [ |
44 | | - 'year' => (int)$d->format('Y'), |
45 | | - 'month' => (int)$d->format('n'), |
46 | | - ]; |
| 38 | +// 四半期定義(年度=4月始まり) |
| 39 | +// Q1: 4-6月, Q2: 7-9月, Q3: 10-12月, Q4: 1-3月(年度+1の暦年) |
| 40 | +function quarterMonths($quarter) { |
| 41 | + $base = [1 => [4,5,6], 2 => [7,8,9], 3 => [10,11,12], 4 => [1,2,3]]; |
| 42 | + return $base[$quarter] ?? [4,5,6]; |
47 | 43 | } |
48 | 44 |
|
| 45 | +// 現在日付から「直近の完了した四半期」を求める |
| 46 | +$cy = (int)$today->format('Y'); |
| 47 | +$cm = (int)$today->format('n'); |
| 48 | +// 暦上の月から年度・四半期を判定 |
| 49 | +if ($cm >= 4 && $cm <= 6) { $cur_fy = $cy; $cur_q = 1; } |
| 50 | +elseif ($cm >= 7 && $cm <= 9) { $cur_fy = $cy; $cur_q = 2; } |
| 51 | +elseif ($cm >= 10 && $cm <= 12) { $cur_fy = $cy; $cur_q = 3; } |
| 52 | +else /* 1-3月 */ { $cur_fy = $cy - 1; $cur_q = 4; } |
| 53 | +// 直近の完了四半期=1つ前 |
| 54 | +if ($cur_q == 1) { $default_fy = $cur_fy - 1; $default_q = 4; } |
| 55 | +else { $default_fy = $cur_fy; $default_q = $cur_q - 1; } |
| 56 | + |
| 57 | +// 年度選択肢(過去5年+今年度) |
| 58 | +$fy_options = []; |
| 59 | +for ($y = $cur_fy; $y >= $cur_fy - 5; $y--) { |
| 60 | + $fy_options[] = $y; |
| 61 | +} |
| 62 | + |
| 63 | +// 選択した年度・四半期から3か月を構築 |
| 64 | +function monthsOfQuarter($fy, $q) { |
| 65 | + $months = quarterMonths($q); |
| 66 | + $year = ($q == 4) ? $fy + 1 : $fy; // Q4は翌年1-3月 |
| 67 | + return array_map(function($m) use ($year) { |
| 68 | + return ['year' => $year, 'month' => $m]; |
| 69 | + }, $months); |
| 70 | +} |
| 71 | +$default_months = monthsOfQuarter($default_fy, $default_q); |
| 72 | + |
49 | 73 | $page_config = getPageConfiguration('taxi_ticket_invoice'); |
50 | 74 | $page_data = renderCompletePage( |
51 | 75 | $page_config['title'], |
|
170 | 194 | <div class="container-fluid mt-3"> |
171 | 195 |
|
172 | 196 | <div class="invoice-toolbar no-print"> |
| 197 | + <div class="d-flex align-items-center gap-2"> |
| 198 | + <label class="form-label mb-0 fw-bold"><i class="fas fa-calendar-alt me-1"></i>請求対象</label> |
| 199 | + <select id="fyPicker" class="form-select form-select-sm" style="width: auto;"> |
| 200 | + <?php foreach ($fy_options as $fy): ?> |
| 201 | + <option value="<?= $fy ?>" <?= $fy === $default_fy ? 'selected' : '' ?>><?= $fy ?>年度</option> |
| 202 | + <?php endforeach; ?> |
| 203 | + </select> |
| 204 | + <select id="quarterPicker" class="form-select form-select-sm" style="width: auto;"> |
| 205 | + <option value="1" <?= $default_q === 1 ? 'selected' : '' ?>>第1四半期(4-6月)</option> |
| 206 | + <option value="2" <?= $default_q === 2 ? 'selected' : '' ?>>第2四半期(7-9月)</option> |
| 207 | + <option value="3" <?= $default_q === 3 ? 'selected' : '' ?>>第3四半期(10-12月)</option> |
| 208 | + <option value="4" <?= $default_q === 4 ? 'selected' : '' ?>>第4四半期(1-3月)</option> |
| 209 | + </select> |
| 210 | + </div> |
173 | 211 | <button class="btn btn-primary" onclick="window.print()"> |
174 | 212 | <i class="fas fa-print me-1"></i>印刷 / PDF保存 |
175 | 213 | </button> |
176 | 214 | <button class="btn btn-outline-secondary" onclick="resetForm()"> |
177 | 215 | <i class="fas fa-eraser me-1"></i>入力クリア |
178 | 216 | </button> |
179 | 217 | <span class="toolbar-hint"> |
180 | | - 乗車料金(680〜570円)× 月別の枚数を入力すると、金額・合計が自動計算されます。 |
| 218 | + 四半期を選ぶと請求対象の3か月が自動セットされます。枚数を入力すると金額・合計を自動計算します。 |
181 | 219 | </span> |
182 | 220 | </div> |
183 | 221 |
|
@@ -382,10 +420,27 @@ function syncMonthLabels() { |
382 | 420 | }); |
383 | 421 | } |
384 | 422 |
|
| 423 | + function applyQuarter() { |
| 424 | + const fy = parseInt(document.getElementById('fyPicker').value, 10); |
| 425 | + const q = parseInt(document.getElementById('quarterPicker').value, 10); |
| 426 | + const monthMap = { 1: [4,5,6], 2: [7,8,9], 3: [10,11,12], 4: [1,2,3] }; |
| 427 | + const months = monthMap[q] || [4,5,6]; |
| 428 | + const year = (q === 4) ? fy + 1 : fy; // Q4は翌年1-3月 |
| 429 | + months.forEach((m, idx) => { |
| 430 | + const yearInput = document.querySelector(`.req-year[data-col="${idx}"]`); |
| 431 | + const monthInput = document.querySelector(`.req-month[data-col="${idx}"]`); |
| 432 | + if (yearInput) yearInput.value = year; |
| 433 | + if (monthInput) monthInput.value = m; |
| 434 | + }); |
| 435 | + syncMonthLabels(); |
| 436 | + } |
| 437 | + |
385 | 438 | document.addEventListener('input', (e) => { |
386 | 439 | if (e.target.matches('.count-input, .fare-other')) recalc(); |
387 | 440 | if (e.target.matches('.req-month')) syncMonthLabels(); |
388 | 441 | }); |
| 442 | + document.getElementById('fyPicker').addEventListener('change', applyQuarter); |
| 443 | + document.getElementById('quarterPicker').addEventListener('change', applyQuarter); |
389 | 444 |
|
390 | 445 | window.resetForm = function() { |
391 | 446 | if (!confirm('入力内容をクリアしますか?')) return; |
|
0 commit comments