Skip to content

Commit 5899e1f

Browse files
hipper-gifclaude
andcommitted
feat: タクシー利用券請求書に四半期選択を追加 [deploy] [fix]
年度+四半期のセレクタを追加し、選択すると請求対象の3か月(Q1=4-6月/Q2=7-9月/Q3=10-12月/Q4=翌1-3月)が自動セットされる。 配置: テスト環境(twinklemark.xsrv.jp)+ 本番(tw1nkle.com Smiley + Lino) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 6488885 commit 5899e1f

1 file changed

Lines changed: 65 additions & 10 deletions

File tree

wts/taxi_ticket_invoice.php

Lines changed: 65 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,41 @@
3535
// 月別明細の乗車料金(紙様式どおり)
3636
$fare_rows = [680, 660, 640, 620, 610, 600, 590, 580, 570];
3737

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];
4743
}
4844

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+
4973
$page_config = getPageConfiguration('taxi_ticket_invoice');
5074
$page_data = renderCompletePage(
5175
$page_config['title'],
@@ -170,14 +194,28 @@
170194
<div class="container-fluid mt-3">
171195

172196
<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>
173211
<button class="btn btn-primary" onclick="window.print()">
174212
<i class="fas fa-print me-1"></i>印刷 / PDF保存
175213
</button>
176214
<button class="btn btn-outline-secondary" onclick="resetForm()">
177215
<i class="fas fa-eraser me-1"></i>入力クリア
178216
</button>
179217
<span class="toolbar-hint">
180-
乗車料金(680〜570円)× 月別の枚数を入力すると、金額・合計が自動計算されます
218+
四半期を選ぶと請求対象の3か月が自動セットされます。枚数を入力すると金額・合計を自動計算します
181219
</span>
182220
</div>
183221

@@ -382,10 +420,27 @@ function syncMonthLabels() {
382420
});
383421
}
384422

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+
385438
document.addEventListener('input', (e) => {
386439
if (e.target.matches('.count-input, .fare-other')) recalc();
387440
if (e.target.matches('.req-month')) syncMonthLabels();
388441
});
442+
document.getElementById('fyPicker').addEventListener('change', applyQuarter);
443+
document.getElementById('quarterPicker').addEventListener('change', applyQuarter);
389444

390445
window.resetForm = function() {
391446
if (!confirm('入力内容をクリアしますか?')) return;

0 commit comments

Comments
 (0)