jp-national-tax 0.1.4 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/lib/jp_national_tax/income_tax/income_kouran_2020.rb +7 -7
- data/lib/jp_national_tax/income_tax/income_kouran_2026.rb +107 -0
- data/lib/jp_national_tax/income_tax/income_nenmatsu_2025.rb +235 -0
- data/lib/jp_national_tax/income_tax/income_nenmatsu_2027.rb +229 -0
- data/lib/jp_national_tax/income_tax.rb +2 -2
- data/lib/jp_national_tax/version.rb +1 -1
- data/tools/README.md +23 -0
- data/tools/analyze-templates-by-proc.rb +60 -0
- data/tools/parse-etax-spec.rb +90 -0
- data/tools/stats-etax-spec.rb +42 -0
- metadata +10 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6076885061229cb2f1952fca326bcf9b2da7f261b424896ed0df768e5e84d7c4
|
|
4
|
+
data.tar.gz: f78a323d3d29ff7e9a2f91be73f32890e9be281f460abbffd40f6ba551fdaed8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5498f8aa0d73407e46db6ea634515b0f43ec12a388bfc67241eb488c8eb66ce09140b565c5b56860426dacdde6306d52bdfe763e9214ce2656ba3a95290a8c0d
|
|
7
|
+
data.tar.gz: 84cf32d1332800ee51381c40a768daa44c6e54479b936dd1b652c592e236c646607b5aa77109fe26e0bde6cea2f442197e84f6b726078f992976e48477f66847
|
data/CHANGELOG.md
CHANGED
|
@@ -85,19 +85,19 @@ module JpNationalTax
|
|
|
85
85
|
|
|
86
86
|
case その月の課税給与所得金額
|
|
87
87
|
when 0 .. 162_500
|
|
88
|
-
(その月の課税給与所得金額 * BigDecimal("0.05105")).round(
|
|
88
|
+
(その月の課税給与所得金額 * BigDecimal("0.05105")).round(-1, BigDecimal::ROUND_HALF_UP)
|
|
89
89
|
when 162_501 .. 275_000
|
|
90
|
-
(その月の課税給与所得金額 * BigDecimal("0.10210")).round(
|
|
90
|
+
(その月の課税給与所得金額 * BigDecimal("0.10210") - 8_296).round(-1, BigDecimal::ROUND_HALF_UP)
|
|
91
91
|
when 275_001 .. 579_166
|
|
92
|
-
(その月の課税給与所得金額 * BigDecimal("0.20420")).round(
|
|
92
|
+
(その月の課税給与所得金額 * BigDecimal("0.20420") - 36_374).round(-1, BigDecimal::ROUND_HALF_UP)
|
|
93
93
|
when 579_001 .. 750_000
|
|
94
|
-
(その月の課税給与所得金額 * BigDecimal("0.23483")).round(
|
|
94
|
+
(その月の課税給与所得金額 * BigDecimal("0.23483") - 54_113).round(-1, BigDecimal::ROUND_HALF_UP)
|
|
95
95
|
when 750_001 .. 1_500_000
|
|
96
|
-
(その月の課税給与所得金額 * BigDecimal("0.33693")).round(
|
|
96
|
+
(その月の課税給与所得金額 * BigDecimal("0.33693") - 130_688).round(-1, BigDecimal::ROUND_HALF_UP)
|
|
97
97
|
when 1_500_001 .. 3_333_333
|
|
98
|
-
(その月の課税給与所得金額 * BigDecimal("0.40840")).round(
|
|
98
|
+
(その月の課税給与所得金額 * BigDecimal("0.40840") - 237_893).round(-1, BigDecimal::ROUND_HALF_UP)
|
|
99
99
|
else
|
|
100
|
-
(その月の課税給与所得金額 * BigDecimal("0.45945")).round(
|
|
100
|
+
(その月の課税給与所得金額 * BigDecimal("0.45945") - 408_061).round(-1, BigDecimal::ROUND_HALF_UP)
|
|
101
101
|
end
|
|
102
102
|
|
|
103
103
|
end
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
require "date"
|
|
3
|
+
require "bigdecimal"
|
|
4
|
+
|
|
5
|
+
module JpNationalTax
|
|
6
|
+
module IncomeTax
|
|
7
|
+
module Kouran2026
|
|
8
|
+
|
|
9
|
+
module_function
|
|
10
|
+
|
|
11
|
+
def effective_date
|
|
12
|
+
Date.parse("2026-01-01")
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
#
|
|
16
|
+
# 月額表の甲欄を適用する給与等につき、電子計算機等を使用して源泉徴収税額を計算する方法
|
|
17
|
+
#
|
|
18
|
+
def monthly_kouran (その月の社会保険料等控除後の給与等の金額, 配偶者 = false, 控除対象扶養親族の数 = 0)
|
|
19
|
+
|
|
20
|
+
b = その月の社会保険料等控除後の給与等の金額
|
|
21
|
+
|
|
22
|
+
配偶者控除の額及び扶養控除の額 = 扶養控除の額 (控除対象扶養親族の数)
|
|
23
|
+
配偶者控除の額及び扶養控除の額 += 配偶者控除の額 if 配偶者
|
|
24
|
+
|
|
25
|
+
課税給与所得金額 = b - 配偶者控除の額及び扶養控除の額 - 給与所得控除の額(b) - 基礎控除の額(b)
|
|
26
|
+
|
|
27
|
+
源泉徴収額 = 税額(課税給与所得金額).to_i
|
|
28
|
+
|
|
29
|
+
if 源泉徴収額 > 0
|
|
30
|
+
源泉徴収額
|
|
31
|
+
else
|
|
32
|
+
0
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def 給与所得控除の額 (その月の社会保険料控除後の給与等の金額)
|
|
39
|
+
|
|
40
|
+
case その月の社会保険料控除後の給与等の金額
|
|
41
|
+
when 0 .. 158_333
|
|
42
|
+
54_167
|
|
43
|
+
when 158_334 .. 299_999
|
|
44
|
+
(その月の社会保険料控除後の給与等の金額 * BigDecimal("0.3")).ceil + 6_667
|
|
45
|
+
when 300_000 .. 549_999
|
|
46
|
+
(その月の社会保険料控除後の給与等の金額 * BigDecimal("0.2")).ceil + 36_667
|
|
47
|
+
when 550_000 .. 708_330
|
|
48
|
+
(その月の社会保険料控除後の給与等の金額 * BigDecimal("0.1")).ceil + 91_667
|
|
49
|
+
else
|
|
50
|
+
162_500
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def 配偶者控除の額
|
|
57
|
+
31_667
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def 扶養控除の額 (控除対象扶養親族の数)
|
|
62
|
+
31_667 * 控除対象扶養親族の数
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def 基礎控除の額 (その月の社会保険料等控除後の給与等の金額)
|
|
67
|
+
|
|
68
|
+
case その月の社会保険料等控除後の給与等の金額
|
|
69
|
+
when 0 .. 2_120_833
|
|
70
|
+
48_334
|
|
71
|
+
when 2_120_834 .. 2_162_499
|
|
72
|
+
40_000
|
|
73
|
+
when 2_162_500 .. 2_204_166
|
|
74
|
+
26_667
|
|
75
|
+
when 2_204_167 .. 2_245_833
|
|
76
|
+
13_334
|
|
77
|
+
else
|
|
78
|
+
0
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def 税額 (その月の課税給与所得金額)
|
|
85
|
+
|
|
86
|
+
case その月の課税給与所得金額
|
|
87
|
+
when 0 .. 162_500
|
|
88
|
+
(その月の課税給与所得金額 * BigDecimal("0.05105")).round(-1, BigDecimal::ROUND_HALF_UP)
|
|
89
|
+
when 162_501 .. 275_000
|
|
90
|
+
(その月の課税給与所得金額 * BigDecimal("0.10210") - 8_296).round(-1, BigDecimal::ROUND_HALF_UP)
|
|
91
|
+
when 275_001 .. 579_166
|
|
92
|
+
(その月の課税給与所得金額 * BigDecimal("0.20420") - 36_374).round(-1, BigDecimal::ROUND_HALF_UP)
|
|
93
|
+
when 579_001 .. 750_000
|
|
94
|
+
(その月の課税給与所得金額 * BigDecimal("0.23483") - 54_113).round(-1, BigDecimal::ROUND_HALF_UP)
|
|
95
|
+
when 750_001 .. 1_500_000
|
|
96
|
+
(その月の課税給与所得金額 * BigDecimal("0.33693") - 130_688).round(-1, BigDecimal::ROUND_HALF_UP)
|
|
97
|
+
when 1_500_001 .. 3_333_333
|
|
98
|
+
(その月の課税給与所得金額 * BigDecimal("0.40840") - 237_893).round(-1, BigDecimal::ROUND_HALF_UP)
|
|
99
|
+
else
|
|
100
|
+
(その月の課税給与所得金額 * BigDecimal("0.45945") - 408_061).round(-1, BigDecimal::ROUND_HALF_UP)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
require "date"
|
|
3
|
+
require "bigdecimal"
|
|
4
|
+
|
|
5
|
+
module JpNationalTax #:nodoc:
|
|
6
|
+
module IncomeTax #:nodoc:
|
|
7
|
+
#
|
|
8
|
+
# https://www.nta.go.jp/publication/pamph/gensen/nencho2025/pdf/204.pdf
|
|
9
|
+
#
|
|
10
|
+
module Nenmatsu2025
|
|
11
|
+
|
|
12
|
+
module_function
|
|
13
|
+
|
|
14
|
+
def effective_date
|
|
15
|
+
Date.parse("2025-12-01")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# 電子計算機等による年末調整
|
|
19
|
+
#
|
|
20
|
+
def 年調給与額(給与の総額)
|
|
21
|
+
case 給与の総額
|
|
22
|
+
when 1_900_000 .. 6_599_999
|
|
23
|
+
階差 = 4_000
|
|
24
|
+
同一階差の最小値 = 1_900_000
|
|
25
|
+
給与の総額 - ((給与の総額 - 同一階差の最小値) % 階差)
|
|
26
|
+
else
|
|
27
|
+
給与の総額
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# 電子計算機等による年末調整
|
|
32
|
+
#
|
|
33
|
+
def 給与所得控除後の給与等の金額(年調給与額)
|
|
34
|
+
case 年調給与額
|
|
35
|
+
when 0 .. 650_999
|
|
36
|
+
0
|
|
37
|
+
when 651_000 .. 1_899_999
|
|
38
|
+
年調給与額 - 650_000
|
|
39
|
+
when 1_900_000 .. 3_599_999
|
|
40
|
+
(年調給与額 * BigDecimal('0.7') + 80_000).floor
|
|
41
|
+
when 3_600_000 .. 6_599_999
|
|
42
|
+
(年調給与額 * BigDecimal('0.8') - 440_000).floor
|
|
43
|
+
when 6_600_000 .. 8_499_999
|
|
44
|
+
(年調給与額 * BigDecimal('0.9') - 1_100_000).floor
|
|
45
|
+
when 8_500_000 .. 20_000_000
|
|
46
|
+
年調給与額 - 1_950_000
|
|
47
|
+
else
|
|
48
|
+
STDERR.puts '年末調整の対象となりません'
|
|
49
|
+
年調給与額 - 1_950_000
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# https://www.nta.go.jp/taxes/shiraberu/taxanswer/shotoku/1199.htm
|
|
54
|
+
#
|
|
55
|
+
def 基礎控除額(所得金額)
|
|
56
|
+
case 所得金額
|
|
57
|
+
when 0 .. 1_320_000
|
|
58
|
+
950_000
|
|
59
|
+
when 1_320_001 .. 3_360_000
|
|
60
|
+
880_000
|
|
61
|
+
when 3_360_001 .. 4_890_000
|
|
62
|
+
680_000
|
|
63
|
+
when 4_890_001 .. 6_550_000
|
|
64
|
+
630_000
|
|
65
|
+
when 6_550_001 .. 23_500_000
|
|
66
|
+
580_000
|
|
67
|
+
when 23_500_001 .. 24_000_000
|
|
68
|
+
480_000
|
|
69
|
+
when 24_000_001 .. 24_500_000
|
|
70
|
+
320_000
|
|
71
|
+
when 24_500_001 .. 25_000_000
|
|
72
|
+
160_000
|
|
73
|
+
else
|
|
74
|
+
0
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def 扶養控除の額(生年月日, 申告年, 所得金額 = 0, 同居: nil)
|
|
79
|
+
return 0 if 生年月日.nil?
|
|
80
|
+
|
|
81
|
+
基準日 = Date.new(申告年, 12, 31)
|
|
82
|
+
if 生年月日 > 基準日.prev_year(16)
|
|
83
|
+
0
|
|
84
|
+
elsif 生年月日 <= 基準日.prev_year(70)
|
|
85
|
+
return 0 if 所得金額 > 580_000
|
|
86
|
+
同居 ? 580_000 : 480_000 # 老人扶養親族
|
|
87
|
+
elsif 生年月日 <= 基準日.prev_year(19) and 生年月日 > 基準日.prev_year(23)
|
|
88
|
+
特定親族特別控除額(所得金額)
|
|
89
|
+
else
|
|
90
|
+
所得金額 > 580_000 ? 0 : 380_000
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def 配偶者特別控除の金額(所得金額, 配偶者の所得金額, 配偶者の生年月日: nil, 申告年: nil)
|
|
95
|
+
return 0 if 所得金額 > 10_000_000
|
|
96
|
+
return 0 if 配偶者の所得金額 > 1_330_000
|
|
97
|
+
|
|
98
|
+
老人控除対象 = if 申告年 and 配偶者の生年月日
|
|
99
|
+
基準日 = Date.new(申告年, 12, 31)
|
|
100
|
+
配偶者の生年月日 <= 基準日.prev_year(70)
|
|
101
|
+
else
|
|
102
|
+
false
|
|
103
|
+
end
|
|
104
|
+
if 所得金額 <= 9_000_000
|
|
105
|
+
case 配偶者の所得金額
|
|
106
|
+
when 0 .. 580_000 # 配偶者控除
|
|
107
|
+
老人控除対象 ? 480_000 : 380_000
|
|
108
|
+
when 580_001 .. 950_000
|
|
109
|
+
380_000
|
|
110
|
+
when 950_001 .. 1_000_000
|
|
111
|
+
360_000
|
|
112
|
+
when 1_000_001 .. 1_050_000
|
|
113
|
+
310_000
|
|
114
|
+
when 1_050_001 .. 1_100_000
|
|
115
|
+
260_000
|
|
116
|
+
when 1_100_001 .. 1_150_000
|
|
117
|
+
210_000
|
|
118
|
+
when 1_150_001 .. 1_200_000
|
|
119
|
+
160_000
|
|
120
|
+
when 1_200_001 .. 1_250_000
|
|
121
|
+
110_000
|
|
122
|
+
when 1_250_001 .. 1_300_000
|
|
123
|
+
60_000
|
|
124
|
+
else
|
|
125
|
+
30_000
|
|
126
|
+
end
|
|
127
|
+
elsif 所得金額 <= 9_500_000
|
|
128
|
+
case 配偶者の所得金額
|
|
129
|
+
when 0 .. 580_000
|
|
130
|
+
老人控除対象 ? 320_000 : 260_000
|
|
131
|
+
when 580_001 .. 950_000
|
|
132
|
+
260_000
|
|
133
|
+
when 950_001 .. 1_000_000
|
|
134
|
+
240_000
|
|
135
|
+
when 1_000_001 .. 1_050_000
|
|
136
|
+
210_000
|
|
137
|
+
when 1_050_001 .. 1_100_000
|
|
138
|
+
180_000
|
|
139
|
+
when 1_100_001 .. 1_150_000
|
|
140
|
+
140_000
|
|
141
|
+
when 1_150_001 .. 1_200_000
|
|
142
|
+
110_000
|
|
143
|
+
when 1_200_001 .. 1_250_000
|
|
144
|
+
80_000
|
|
145
|
+
when 1_250_001 .. 1_300_000
|
|
146
|
+
40_000
|
|
147
|
+
else
|
|
148
|
+
20_000
|
|
149
|
+
end
|
|
150
|
+
else
|
|
151
|
+
case 配偶者の所得金額
|
|
152
|
+
when 0 .. 580_000
|
|
153
|
+
老人控除対象 ? 160_000 : 130_000
|
|
154
|
+
when 580_001 .. 950_000
|
|
155
|
+
130_000
|
|
156
|
+
when 950_001 .. 1_000_000
|
|
157
|
+
120_000
|
|
158
|
+
when 1_000_001 .. 1_050_000
|
|
159
|
+
110_000
|
|
160
|
+
when 1_050_001 .. 1_100_000
|
|
161
|
+
90_000
|
|
162
|
+
when 1_100_001 .. 1_150_000
|
|
163
|
+
70_000
|
|
164
|
+
when 1_150_001 .. 1_200_000
|
|
165
|
+
60_000
|
|
166
|
+
when 1_200_001 .. 1_250_000
|
|
167
|
+
40_000
|
|
168
|
+
when 1_250_001 .. 1_300_000
|
|
169
|
+
20_000
|
|
170
|
+
else
|
|
171
|
+
10_000
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def 特定親族特別控除額(所得金額)
|
|
177
|
+
return 630_000 if 所得金額.nil? # 特定扶養親族
|
|
178
|
+
|
|
179
|
+
case 所得金額
|
|
180
|
+
when 0 .. 580_000
|
|
181
|
+
630_000 # 特定扶養親族
|
|
182
|
+
when 580_001 .. 850_000
|
|
183
|
+
630_000
|
|
184
|
+
when 850_001 .. 900_000
|
|
185
|
+
610_000
|
|
186
|
+
when 900_001 .. 950_000
|
|
187
|
+
510_000
|
|
188
|
+
when 950_001 .. 1_000_000
|
|
189
|
+
410_000
|
|
190
|
+
when 1_000_001 .. 1_050_000
|
|
191
|
+
310_000
|
|
192
|
+
when 1_050_001 .. 1_100_000
|
|
193
|
+
210_000
|
|
194
|
+
when 1_100_001 .. 1_150_000
|
|
195
|
+
110_000
|
|
196
|
+
when 1_150_001 .. 1_200_000
|
|
197
|
+
60_000
|
|
198
|
+
when 1_200_001 .. 1_230_000
|
|
199
|
+
30_000
|
|
200
|
+
else
|
|
201
|
+
0
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
# 電子計算機等による年末調整
|
|
206
|
+
#
|
|
207
|
+
def 算出所得税額(課税給与所得金額)
|
|
208
|
+
tax = case 課税給与所得金額
|
|
209
|
+
when 0 .. 1_950_000
|
|
210
|
+
課税給与所得金額 * 0.05
|
|
211
|
+
when 1_950_001 .. 3_300_000
|
|
212
|
+
課税給与所得金額 * 0.1 - 97_500
|
|
213
|
+
when 3_300_001 .. 6_950_000
|
|
214
|
+
課税給与所得金額 * 0.2 - 427_500
|
|
215
|
+
when 6_950_001 .. 9_000_000
|
|
216
|
+
課税給与所得金額 * 0.23 - 636_000
|
|
217
|
+
when 9_000_001 .. 18_000_000
|
|
218
|
+
課税給与所得金額 * 0.33 - 1_536_000
|
|
219
|
+
when 18_000_001 .. 18_050_000
|
|
220
|
+
課税給与所得金額 * 0.4 - 2_796_000
|
|
221
|
+
else
|
|
222
|
+
raise '年末調整の対象となりません'
|
|
223
|
+
end
|
|
224
|
+
(tax / 1000).floor * 1000
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# 電子計算機等による年末調整
|
|
228
|
+
#
|
|
229
|
+
def 年調年税額(年調所得税額)
|
|
230
|
+
(年調所得税額 * BigDecimal('1.021') / 100).floor * 100
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
end
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
require "date"
|
|
3
|
+
require "bigdecimal"
|
|
4
|
+
|
|
5
|
+
module JpNationalTax #:nodoc:
|
|
6
|
+
module IncomeTax #:nodoc:
|
|
7
|
+
#
|
|
8
|
+
# https://www.nta.go.jp/publication/pamph/gensen/nencho2025/pdf/204.pdf
|
|
9
|
+
#
|
|
10
|
+
module Nenmatsu2027
|
|
11
|
+
|
|
12
|
+
module_function
|
|
13
|
+
|
|
14
|
+
def effective_date
|
|
15
|
+
Date.parse("2027-12-01")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# 電子計算機等による年末調整
|
|
19
|
+
#
|
|
20
|
+
def 年調給与額(給与の総額)
|
|
21
|
+
case 給与の総額
|
|
22
|
+
when 1_900_000 .. 6_599_999
|
|
23
|
+
階差 = 4_000
|
|
24
|
+
同一階差の最小値 = 1_900_000
|
|
25
|
+
給与の総額 - ((給与の総額 - 同一階差の最小値) % 階差)
|
|
26
|
+
else
|
|
27
|
+
給与の総額
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# 電子計算機等による年末調整
|
|
32
|
+
#
|
|
33
|
+
def 給与所得控除後の給与等の金額(年調給与額)
|
|
34
|
+
case 年調給与額
|
|
35
|
+
when 0 .. 650_999
|
|
36
|
+
0
|
|
37
|
+
when 651_000 .. 1_899_999
|
|
38
|
+
年調給与額 - 650_000
|
|
39
|
+
when 1_900_000 .. 3_599_999
|
|
40
|
+
(年調給与額 * BigDecimal('0.7') + 80_000).floor
|
|
41
|
+
when 3_600_000 .. 6_599_999
|
|
42
|
+
(年調給与額 * BigDecimal('0.8') - 440_000).floor
|
|
43
|
+
when 6_600_000 .. 8_499_999
|
|
44
|
+
(年調給与額 * BigDecimal('0.9') - 1_100_000).floor
|
|
45
|
+
when 8_500_000 .. 20_000_000
|
|
46
|
+
年調給与額 - 1_950_000
|
|
47
|
+
else
|
|
48
|
+
STDERR.puts '年末調整の対象となりません'
|
|
49
|
+
年調給与額 - 1_950_000
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# https://www.nta.go.jp/taxes/shiraberu/taxanswer/shotoku/1199.htm
|
|
54
|
+
#
|
|
55
|
+
def 基礎控除額(所得金額)
|
|
56
|
+
case 所得金額
|
|
57
|
+
when 0 .. 1_320_000
|
|
58
|
+
950_000
|
|
59
|
+
when 1_320_001 .. 23_500_000
|
|
60
|
+
580_000
|
|
61
|
+
when 23_500_001 .. 24_000_000
|
|
62
|
+
480_000
|
|
63
|
+
when 24_000_001 .. 24_500_000
|
|
64
|
+
320_000
|
|
65
|
+
when 24_500_001 .. 25_000_000
|
|
66
|
+
160_000
|
|
67
|
+
else
|
|
68
|
+
0
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def 扶養控除の額(生年月日, 申告年, 所得金額 = 0, 同居: nil)
|
|
73
|
+
return 0 if 生年月日.nil?
|
|
74
|
+
|
|
75
|
+
基準日 = Date.new(申告年, 12, 31)
|
|
76
|
+
if 生年月日 > 基準日.prev_year(16)
|
|
77
|
+
0
|
|
78
|
+
elsif 生年月日 <= 基準日.prev_year(70)
|
|
79
|
+
return 0 if 所得金額 > 580_000
|
|
80
|
+
同居 ? 580_000 : 480_000 # 老人扶養親族
|
|
81
|
+
elsif 生年月日 <= 基準日.prev_year(19) and 生年月日 > 基準日.prev_year(23)
|
|
82
|
+
特定親族特別控除額(所得金額)
|
|
83
|
+
else
|
|
84
|
+
所得金額 > 580_000 ? 0 : 380_000
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def 配偶者特別控除の金額(所得金額, 配偶者の所得金額, 配偶者の生年月日: nil, 申告年: nil)
|
|
89
|
+
return 0 if 所得金額 > 10_000_000
|
|
90
|
+
return 0 if 配偶者の所得金額 > 1_330_000
|
|
91
|
+
|
|
92
|
+
老人控除対象 = if 申告年 and 配偶者の生年月日
|
|
93
|
+
基準日 = Date.new(申告年, 12, 31)
|
|
94
|
+
配偶者の生年月日 <= 基準日.prev_year(70)
|
|
95
|
+
else
|
|
96
|
+
false
|
|
97
|
+
end
|
|
98
|
+
if 所得金額 <= 9_000_000
|
|
99
|
+
case 配偶者の所得金額
|
|
100
|
+
when 0 .. 580_000 # 配偶者控除
|
|
101
|
+
老人控除対象 ? 480_000 : 380_000
|
|
102
|
+
when 580_001 .. 950_000
|
|
103
|
+
380_000
|
|
104
|
+
when 950_001 .. 1_000_000
|
|
105
|
+
360_000
|
|
106
|
+
when 1_000_001 .. 1_050_000
|
|
107
|
+
310_000
|
|
108
|
+
when 1_050_001 .. 1_100_000
|
|
109
|
+
260_000
|
|
110
|
+
when 1_100_001 .. 1_150_000
|
|
111
|
+
210_000
|
|
112
|
+
when 1_150_001 .. 1_200_000
|
|
113
|
+
160_000
|
|
114
|
+
when 1_200_001 .. 1_250_000
|
|
115
|
+
110_000
|
|
116
|
+
when 1_250_001 .. 1_300_000
|
|
117
|
+
60_000
|
|
118
|
+
else
|
|
119
|
+
30_000
|
|
120
|
+
end
|
|
121
|
+
elsif 所得金額 <= 9_500_000
|
|
122
|
+
case 配偶者の所得金額
|
|
123
|
+
when 0 .. 580_000
|
|
124
|
+
老人控除対象 ? 320_000 : 260_000
|
|
125
|
+
when 580_001 .. 950_000
|
|
126
|
+
260_000
|
|
127
|
+
when 950_001 .. 1_000_000
|
|
128
|
+
240_000
|
|
129
|
+
when 1_000_001 .. 1_050_000
|
|
130
|
+
210_000
|
|
131
|
+
when 1_050_001 .. 1_100_000
|
|
132
|
+
180_000
|
|
133
|
+
when 1_100_001 .. 1_150_000
|
|
134
|
+
140_000
|
|
135
|
+
when 1_150_001 .. 1_200_000
|
|
136
|
+
110_000
|
|
137
|
+
when 1_200_001 .. 1_250_000
|
|
138
|
+
80_000
|
|
139
|
+
when 1_250_001 .. 1_300_000
|
|
140
|
+
40_000
|
|
141
|
+
else
|
|
142
|
+
20_000
|
|
143
|
+
end
|
|
144
|
+
else
|
|
145
|
+
case 配偶者の所得金額
|
|
146
|
+
when 0 .. 580_000
|
|
147
|
+
老人控除対象 ? 160_000 : 130_000
|
|
148
|
+
when 580_001 .. 950_000
|
|
149
|
+
130_000
|
|
150
|
+
when 950_001 .. 1_000_000
|
|
151
|
+
120_000
|
|
152
|
+
when 1_000_001 .. 1_050_000
|
|
153
|
+
110_000
|
|
154
|
+
when 1_050_001 .. 1_100_000
|
|
155
|
+
90_000
|
|
156
|
+
when 1_100_001 .. 1_150_000
|
|
157
|
+
70_000
|
|
158
|
+
when 1_150_001 .. 1_200_000
|
|
159
|
+
60_000
|
|
160
|
+
when 1_200_001 .. 1_250_000
|
|
161
|
+
40_000
|
|
162
|
+
when 1_250_001 .. 1_300_000
|
|
163
|
+
20_000
|
|
164
|
+
else
|
|
165
|
+
10_000
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def 特定親族特別控除額(所得金額)
|
|
171
|
+
return 630_000 if 所得金額.nil? # 特定扶養親族
|
|
172
|
+
|
|
173
|
+
case 所得金額
|
|
174
|
+
when 0 .. 580_000
|
|
175
|
+
630_000 # 特定扶養親族
|
|
176
|
+
when 580_001 .. 850_000
|
|
177
|
+
630_000
|
|
178
|
+
when 850_001 .. 900_000
|
|
179
|
+
610_000
|
|
180
|
+
when 900_001 .. 950_000
|
|
181
|
+
510_000
|
|
182
|
+
when 950_001 .. 1_000_000
|
|
183
|
+
410_000
|
|
184
|
+
when 1_000_001 .. 1_050_000
|
|
185
|
+
310_000
|
|
186
|
+
when 1_050_001 .. 1_100_000
|
|
187
|
+
210_000
|
|
188
|
+
when 1_100_001 .. 1_150_000
|
|
189
|
+
110_000
|
|
190
|
+
when 1_150_001 .. 1_200_000
|
|
191
|
+
60_000
|
|
192
|
+
when 1_200_001 .. 1_230_000
|
|
193
|
+
30_000
|
|
194
|
+
else
|
|
195
|
+
0
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# 電子計算機等による年末調整
|
|
200
|
+
#
|
|
201
|
+
def 算出所得税額(課税給与所得金額)
|
|
202
|
+
tax = case 課税給与所得金額
|
|
203
|
+
when 0 .. 1_950_000
|
|
204
|
+
課税給与所得金額 * 0.05
|
|
205
|
+
when 1_950_001 .. 3_300_000
|
|
206
|
+
課税給与所得金額 * 0.1 - 97_500
|
|
207
|
+
when 3_300_001 .. 6_950_000
|
|
208
|
+
課税給与所得金額 * 0.2 - 427_500
|
|
209
|
+
when 6_950_001 .. 9_000_000
|
|
210
|
+
課税給与所得金額 * 0.23 - 636_000
|
|
211
|
+
when 9_000_001 .. 18_000_000
|
|
212
|
+
課税給与所得金額 * 0.33 - 1_536_000
|
|
213
|
+
when 18_000_001 .. 18_050_000
|
|
214
|
+
課税給与所得金額 * 0.4 - 2_796_000
|
|
215
|
+
else
|
|
216
|
+
raise '年末調整の対象となりません'
|
|
217
|
+
end
|
|
218
|
+
(tax / 1000).floor * 1000
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
# 電子計算機等による年末調整
|
|
222
|
+
#
|
|
223
|
+
def 年調年税額(年調所得税額)
|
|
224
|
+
(年調所得税額 * BigDecimal('1.021') / 100).floor * 100
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
end
|
|
@@ -5,8 +5,8 @@ Dir[File.expand_path("income_tax/income*.rb", __dir__)].each { |f| require_relat
|
|
|
5
5
|
|
|
6
6
|
module JpNationalTax
|
|
7
7
|
module IncomeTax
|
|
8
|
-
MOD_M = [Kouran2020]
|
|
9
|
-
MOD_Y = [Nenmatsu2020]
|
|
8
|
+
MOD_M = [Kouran2026, Kouran2020]
|
|
9
|
+
MOD_Y = [Nenmatsu2027, Nenmatsu2025, Nenmatsu2020]
|
|
10
10
|
|
|
11
11
|
module_function
|
|
12
12
|
|
data/tools/README.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# eTax仕様比較ツール
|
|
2
|
+
|
|
3
|
+
[e-Tax仕様書](https://www.e-tax.nta.go.jp/shiyo/index.htm#anc05)の申告技術仕様のxlsxをもとに、バージョン間の異同を分析するツール。
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## 手続きバージョンごとの帳票バージョンリスト
|
|
7
|
+
|
|
8
|
+
各手続きバージョンに対応する帳票バージョンのセットを特定する用途。
|
|
9
|
+
|
|
10
|
+
1. `analyze-templates-by-proc.rb`を用いてレポートファイルを生成
|
|
11
|
+
* 手続きIDを指定
|
|
12
|
+
* `07手続一覧等/02手続内帳票対応表/`の分析対象xlsxファイルを指定。ワイルドカード利用可能
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
## 帳票バージョンとフィールドの対応リスト
|
|
16
|
+
|
|
17
|
+
各帳票フィールドの追加・削除を特定する用途。
|
|
18
|
+
フィールドの追加・削除は把握できるが、定義の異同はチェックしていない。
|
|
19
|
+
|
|
20
|
+
1. `parse-etax-spec.rb`を用いてxlsxをtsvに変換
|
|
21
|
+
* `10XML構造設計書等【法人税】/`の分析対象xlsxファイルを指定。ワイルドカード利用可能
|
|
22
|
+
2. `stats-etax-spec.rb`を用いてレポートファイルを生成
|
|
23
|
+
* 帳票IDを指定
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require "csv"
|
|
3
|
+
require "roo"
|
|
4
|
+
|
|
5
|
+
#
|
|
6
|
+
# eTax仕様の手続内帳票対応表をTSV変換するツール
|
|
7
|
+
#
|
|
8
|
+
def print_usage
|
|
9
|
+
# ARGV[1..]にはExcelファイルのpathを指定
|
|
10
|
+
STDERR.puts "Usage: ruby analyze-templates-by-proc.rb <手続code> <手続内帳票対応表.xlsx files>"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def search_proc(sheet, proc_id)
|
|
14
|
+
{}.tap do |templates|
|
|
15
|
+
sheet.each do |row|
|
|
16
|
+
next if row[0] != proc_id
|
|
17
|
+
|
|
18
|
+
if templates[row[2]]
|
|
19
|
+
templates[row[2]][:template_ver].push(row[9])
|
|
20
|
+
else
|
|
21
|
+
template = { :name => row[1], :proc_ver => row[8], :template_ver => Array(row[9]) }
|
|
22
|
+
templates[row[2]] = template
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
if templates.empty?
|
|
26
|
+
STDERR.puts " #{proc_id} not found"
|
|
27
|
+
return nil
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
if ARGV.length < 2
|
|
33
|
+
print_usage
|
|
34
|
+
exit 1
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
proc_id = ARGV[0]
|
|
38
|
+
filename = "#{proc_id}.tsv"
|
|
39
|
+
[].tap do |procs|
|
|
40
|
+
ARGV[1..-1].each do |path|
|
|
41
|
+
xlsx = Roo::Excelx.new(path, expand_merged_ranges: true)
|
|
42
|
+
STDERR.puts "Processing... #{path}"
|
|
43
|
+
xlsx.each_with_pagename do |name, sheet|
|
|
44
|
+
procedure = search_proc(sheet, proc_id)
|
|
45
|
+
procs.push(procedure) if procedure
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
keys = procs.map {|procedure| procedure.keys }.flatten.uniq.sort
|
|
50
|
+
|
|
51
|
+
CSV.open(filename, "w", col_sep: "\t", force_quotes: true, quote_char: '"') do |csv|
|
|
52
|
+
csv << ["帳票ID", "帳票名"].concat(procs.map {|procedure| procedure.first&.last&.fetch(:proc_ver)})
|
|
53
|
+
keys.each do |k|
|
|
54
|
+
name = procs.map {|procedure| procedure.dig(k, :name) }.compact.first
|
|
55
|
+
csv << [k, name].concat(procs.map {|procedure| procedure[k]&.fetch(:template_ver)&.join('|')})
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
STDERR.puts "\n#{filename} saved"
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require "csv"
|
|
3
|
+
require "roo"
|
|
4
|
+
|
|
5
|
+
#
|
|
6
|
+
# eTax仕様のXML構造設計書をTSV変換するツール
|
|
7
|
+
#
|
|
8
|
+
|
|
9
|
+
TARGET_COLUMNS = {
|
|
10
|
+
origin: ["タグ名", "レベル", "共通ボキャブラリまたはデータ型", "項番", "備考"],
|
|
11
|
+
dest: ["version", "tag", "level", "struct", "order", "note", "label"],
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
def print_usage
|
|
15
|
+
STDERR.puts "Usage: ruby parse-etax-spec.rb <XML構造設計書.xlsx files>"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def search_columns(xlsx)
|
|
19
|
+
[].tap do |columns|
|
|
20
|
+
xlsx.each_row_streaming do |row|
|
|
21
|
+
next if row[0].value != "項番"
|
|
22
|
+
|
|
23
|
+
TARGET_COLUMNS[:origin].each do |label|
|
|
24
|
+
columns.push row.find_index { |cell| cell.value == label }
|
|
25
|
+
end
|
|
26
|
+
break
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def collect_rows(xlsx, columns)
|
|
32
|
+
[].tap do |res|
|
|
33
|
+
xlsx.each_row_streaming do |row|
|
|
34
|
+
next unless row[0].value.to_s =~ /^[0-9]+$/
|
|
35
|
+
|
|
36
|
+
label = extract_label(row, columns[1], columns[2])
|
|
37
|
+
res.push(columns.map{ |col| row[col].value }.push(label))
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def extract_label(row, prev, subs)
|
|
43
|
+
(prev+1...subs).map { |idx| row[idx].value }.join("")
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def sheet_defs(xlsx)
|
|
47
|
+
columns = []
|
|
48
|
+
xlsx.each_row_streaming do |row|
|
|
49
|
+
next if row[0].value != "帳票名称"
|
|
50
|
+
|
|
51
|
+
["様式ID", "帳票名称", "バージョン"].each do |label|
|
|
52
|
+
columns.push row.find_index { |cell| cell.value == label }
|
|
53
|
+
end
|
|
54
|
+
break
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
[].tap { |res|
|
|
58
|
+
xlsx.each_row_streaming do |row|
|
|
59
|
+
next if row[0].value == "帳票名称"
|
|
60
|
+
|
|
61
|
+
res.push columns.map { |i| row[i].value }
|
|
62
|
+
break
|
|
63
|
+
end
|
|
64
|
+
}.flatten
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
# ARGVにはExcelファイルのpathを指定
|
|
69
|
+
if ARGV.length < 1
|
|
70
|
+
print_usage
|
|
71
|
+
exit 1
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
ARGV.each do |path|
|
|
75
|
+
xlsx = Roo::Excelx.new(path)
|
|
76
|
+
STDERR.puts "Processing... #{path}"
|
|
77
|
+
|
|
78
|
+
xlsx.each_with_pagename do |name, sheet|
|
|
79
|
+
id, name, version = sheet_defs(xlsx)
|
|
80
|
+
filename = "#{id}-#{version}-#{name.gsub(/\//, '=')[0, 80]}.tsv"
|
|
81
|
+
columns = search_columns(sheet)
|
|
82
|
+
|
|
83
|
+
CSV.open(filename, "w", col_sep: "\t") do |csv|
|
|
84
|
+
csv << TARGET_COLUMNS[:dest]
|
|
85
|
+
collect_rows(xlsx, columns).each do |row|
|
|
86
|
+
csv << row.unshift(version)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require "csv"
|
|
3
|
+
|
|
4
|
+
def print_usage
|
|
5
|
+
STDERR.puts "eTax仕様を変換したTSVを集計して、タグの有効バージョンをリストするツール\n"
|
|
6
|
+
STDERR.puts "Usage: ruby stats-etax-spec.rb <帳票コード>"
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def accumulate_versions(attr, csv)
|
|
10
|
+
csv.each do |row|
|
|
11
|
+
attr[row['tag']] ||= { versions: [] }
|
|
12
|
+
attr[row['tag']][:versions].push(row['version'])
|
|
13
|
+
attr[row['tag']][:label] = row['label']
|
|
14
|
+
attr[row['tag']][:level] = row['level']
|
|
15
|
+
attr[row['tag']][:order] = row['order']
|
|
16
|
+
attr[row['tag']][:struct] = row['struct']
|
|
17
|
+
attr[row['tag']][:note] = row['note']
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# ARGV[0]には帳票コード(ファイル名の一部)を指定
|
|
22
|
+
if ARGV.length < 1
|
|
23
|
+
print_usage
|
|
24
|
+
exit 1
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
attr = {}
|
|
28
|
+
Dir.glob("#{ARGV[0]}*.tsv").each do |path|
|
|
29
|
+
CSV.open(path, "r", col_sep: "\t", headers: true) do |csv|
|
|
30
|
+
STDERR.puts "Processing... #{path}"
|
|
31
|
+
accumulate_versions(attr, csv)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
output = "stats-#{ARGV[0]}.tsv"
|
|
35
|
+
CSV.open(output, "w", col_sep: "\t") do |csv|
|
|
36
|
+
csv << ["tag", "count", "level", "versions", "order", "label", "struct", "note"]
|
|
37
|
+
attr.each do |k, v|
|
|
38
|
+
csv << [k, v[:versions].length, v[:level], v[:versions].join(', '), v[:order], v[:label], v[:struct], v[:note]]
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
STDERR.puts "\n#{output} saved"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jp-national-tax
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Chuma Takahiro
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-01-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -73,8 +73,15 @@ files:
|
|
|
73
73
|
- lib/jp_national_tax.rb
|
|
74
74
|
- lib/jp_national_tax/income_tax.rb
|
|
75
75
|
- lib/jp_national_tax/income_tax/income_kouran_2020.rb
|
|
76
|
+
- lib/jp_national_tax/income_tax/income_kouran_2026.rb
|
|
76
77
|
- lib/jp_national_tax/income_tax/income_nenmatsu_2020.rb
|
|
78
|
+
- lib/jp_national_tax/income_tax/income_nenmatsu_2025.rb
|
|
79
|
+
- lib/jp_national_tax/income_tax/income_nenmatsu_2027.rb
|
|
77
80
|
- lib/jp_national_tax/version.rb
|
|
81
|
+
- tools/README.md
|
|
82
|
+
- tools/analyze-templates-by-proc.rb
|
|
83
|
+
- tools/parse-etax-spec.rb
|
|
84
|
+
- tools/stats-etax-spec.rb
|
|
78
85
|
homepage: https://github.com/chumaltd/jp-national-tax
|
|
79
86
|
licenses: []
|
|
80
87
|
metadata:
|
|
@@ -96,7 +103,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
96
103
|
- !ruby/object:Gem::Version
|
|
97
104
|
version: '0'
|
|
98
105
|
requirements: []
|
|
99
|
-
rubygems_version: 3.4.
|
|
106
|
+
rubygems_version: 3.4.20
|
|
100
107
|
signing_key:
|
|
101
108
|
specification_version: 4
|
|
102
109
|
summary: Tax calculation libs for Japan National tax
|