luca-jp 0.1.1 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -22,19 +22,20 @@ module Luca
22
22
  set_pl(4)
23
23
  set_bs(4)
24
24
  @issue_date = Date.today
25
- @company = CGI.escapeHTML(LucaSupport::CONFIG.dig('company', 'name'))
25
+ @company = CGI.escapeHTML(config.dig('company', 'name'))
26
26
  @software = 'LucaJp'
27
- @jimusho_code = LucaSupport::CONFIG.dig('jp', 'eltax', 'jimusho_code')
27
+ @jimusho_code = config.dig('jp', 'eltax', 'jimusho_code')
28
28
  @jimusho_name = '都税事務所長'
29
29
 
30
- @均等割 = 70000
30
+ @税額 = 税額計算
31
+ @均等割 = @税額.dig(:kenmin, :kintou)
31
32
  @法人税割課税標準 = 法人税割課税標準
32
- @確定法人税割 = (法人税割 / 100).floor * 100
33
+ @確定法人税割 = (@税額.dig(:kenmin, :houjinzei) / 100).floor * 100
33
34
  @地方特別法人事業税中間納付 = prepaid_tax('1854')
34
35
  @所得割中間納付 = prepaid_tax('1855')
35
36
  @法人税割中間納付 = prepaid_tax('1859')
36
37
  @均等割中間納付 = prepaid_tax('185A')
37
- @所得割 = 所得割400万以下 + 所得割800万以下 + 所得割800万超
38
+ @所得割 = @税額.dig(:kenmin, :shotoku)
38
39
  if export
39
40
  {
40
41
  jigyouzei: {
@@ -43,7 +44,7 @@ module Luca
43
44
  chukan: @所得割中間納付
44
45
  },
45
46
  tokubetsu: {
46
- zeigaku: 地方法人特別税(@所得割),
47
+ zeigaku: @税額.dig(:kenmin, :tokubetsu),
47
48
  chukan: @地方特別法人事業税中間納付
48
49
  },
49
50
  },
@@ -61,9 +62,9 @@ module Luca
61
62
  else
62
63
  @procedure_code = 'R0102100'
63
64
  @procedure_name = '法人都道府県民税・事業税・特別法人事業税又は地方法人特別税 確定申告'
64
- @form_sec = ['R0102AA190', 'R0102AG120'].map{ |c| form_attr(c) }.join('')
65
+ @form_sec = ['R0102AA190', 'R0102AG120', 別表九フォーム].compact.map{ |c| form_attr(c) }.join('')
65
66
  @user_inf = render_erb(search_template('el-userinf.xml.erb'))
66
- @form_data = [第六号, 別表四三].join("\n")
67
+ @form_data = [第六号, 別表四三, 別表九].compact.join("\n")
67
68
  render_erb(search_template('eltax.xml.erb'))
68
69
  end
69
70
  end
@@ -80,22 +81,22 @@ module Luca
80
81
  item['credit'] << { 'label' => karibarai_label(k), 'amount' => dat[:chukan] }
81
82
  end
82
83
  if dat[:chukan] > dat[:zeigaku]
83
- item['debit'] << { 'label' => '未収法人税', 'amount' => dat[:chukan] - dat[:zeigaku] }
84
+ item['debit'] << { 'label' => '未収地方事業税', 'amount' => dat[:chukan] - dat[:zeigaku] }
84
85
  else
85
86
  item['credit'] << { 'label' => '未払地方事業税', 'amount' => dat[:zeigaku] - dat[:chukan] }
86
87
  end
87
- item['debit'] << { 'label' => '法人税、住民税及び事業税', 'amount' => dat[:zeigaku] }
88
+ item['debit'] << { 'label' => '法人税、住民税及び事業税', 'amount' => dat[:zeigaku] } if dat[:zeigaku] > 0
88
89
  end
89
90
  records[:juminzei].each do |k, dat|
90
91
  if dat[:chukan] > 0
91
92
  item['credit'] << { 'label' => karibarai_label(k), 'amount' => dat[:chukan] }
92
93
  end
93
94
  if dat[:chukan] > dat[:zeigaku]
94
- item['debit'] << { 'label' => '未収法人税', 'amount' => dat[:chukan] - dat[:zeigaku] }
95
+ item['debit'] << { 'label' => '未収都道府県住民税', 'amount' => dat[:chukan] - dat[:zeigaku] }
95
96
  else
96
97
  item['credit'] << { 'label' => '未払都道府県民税', 'amount' => dat[:zeigaku] - dat[:chukan] }
97
98
  end
98
- item['debit'] << { 'label' => '法人税、住民税及び事業税', 'amount' => dat[:zeigaku] }
99
+ item['debit'] << { 'label' => '法人税、住民税及び事業税', 'amount' => dat[:zeigaku] } if dat[:zeigaku] > 0
99
100
  end
100
101
  item['x-editor'] = 'LucaJp'
101
102
  res << item
@@ -108,65 +109,61 @@ module Luca
108
109
  end
109
110
 
110
111
  def 別表四三
111
- @office_23ku = LucaSupport::CONFIG.dig('jp', 'eltax', 'office_23ku')
112
+ @office_23ku = config.dig('jp', 'eltax', 'office_23ku')
112
113
  render_erb(search_template('el-no6-43.xml.erb'))
113
114
  end
114
115
 
115
- private
116
-
117
- def 法人税割課税標準
118
- national_tax = Luca::Jp::Aoiro.range(@start_date.year, @start_date.month, @end_date.year, @end_date.month).kani(export: true)
119
- (national_tax[:kokuzei][:zeigaku] / 1000).floor * 1000
120
- end
116
+ def 別表九フォーム
117
+ return nil if @繰越損失管理.records.length == 0
121
118
 
122
- def 法人税割
123
- (@法人税割課税標準 * 7 / 100).floor
119
+ 'R0102AM190'
124
120
  end
125
121
 
126
- def 地方法人特別税(事業税)
127
- ((事業税 * 37 / 100) / 100).floor * 100
128
- end
122
+ def 別表九
123
+ return nil if @繰越損失管理.records.length == 0
129
124
 
130
- def 所得400万以下
131
- if 所得金額 >= 4_000_000
132
- 4_000_000
133
- else
134
- (所得金額 / 1000).floor * 1000
135
- end
125
+ render_erb(search_template('el-no6-9.xml.erb'))
136
126
  end
137
127
 
138
- def 所得割400万以下
139
- ((所得400万以下 * 3.5 / 100) / 100).floor * 100
140
- end
128
+ private
141
129
 
142
- def 所得800万以下
143
- if 所得金額 <= 4_000_000
144
- 0
145
- elsif 所得金額 >= 8_000_000
146
- 4_000_000
147
- else
148
- ((所得金額 - 4_000_000) / 1000).floor * 1000
149
- end
130
+ def 法人税割課税標準
131
+ national_tax = Luca::Jp::Aoiro.range(@start_date.year, @start_date.month, @end_date.year, @end_date.month).kani(export: true)
132
+ (national_tax[:kokuzei][:zeigaku] / 1000).floor * 1000
150
133
  end
151
134
 
152
- def 所得割800万以下
153
- ((所得800万以下 * 5.3 / 100) / 100).floor * 100
135
+ def 事業税中間納付
136
+ @所得割中間納付
154
137
  end
155
138
 
156
- def 所得800万超
157
- if 所得金額 <= 8_000_000
158
- 0
159
- else
160
- ((所得金額 - 8_000_000) / 1000).floor * 1000
139
+ # TODO: 損失の区分
140
+ #
141
+ def 別表九各期青色損失
142
+ tags = @繰越損失管理.records
143
+ .filter { |record| record['start_date'] > @end_date.prev_year(10) && record['end_date'] < @start_date }
144
+ .map do |record|
145
+ deduction = record['decrease']&.filter{ |r| r['date'] >= @start_date }&.dig(0, 'val') || 0
146
+ next if deduction == 0 && record['amount'] == 0
147
+
148
+ %Q(<AMB00200>
149
+ <AMB00210>#{etax_date(@start_date)}</AMB00210>
150
+ <AMB00220>#{etax_date(@end_date)}</AMB00220>
151
+ <AMB00225 />
152
+ #{render_attr('AMB00230', deduction + record['amount'])}
153
+ #{render_attr('AMB00240', deduction)}
154
+ #{render_attr('AMB00250', record['amount'])}
155
+ </AMB00200>)
161
156
  end
162
- end
163
-
164
- def 所得割800万超
165
- ((所得800万超 * 7.0 / 100) / 100).floor * 100
166
- end
157
+ return tags.compact.join("\n") if tags.length > 0
167
158
 
168
- def 事業税中間納付
169
- @所得割中間納付
159
+ %Q(<AMB00200>
160
+ <AMB00210><gen:era /><gen:yy /><gen:mm /><gen:dd /></AMB00210>
161
+ <AMB00220><gen:era /><gen:yy /><gen:mm /><gen:dd /></AMB00220>
162
+ <AMB00225 />
163
+ <AMB00230 />
164
+ <AMB00240 />
165
+ <AMB00250 />
166
+ </AMB00200>)
170
167
  end
171
168
 
172
169
  def form_attr(code)
@@ -185,7 +182,7 @@ module Luca
185
182
  '仮払地方税資本割'
186
183
  when :fukakachi
187
184
  '仮払地方税付加価値割'
188
- when :hojinzei
185
+ when :houjinzei
189
186
  '仮払地方税法人税割'
190
187
  when :kinto
191
188
  '仮払地方税均等割'
@@ -7,13 +7,180 @@ module Luca
7
7
  module Common
8
8
  module_function
9
9
 
10
+ # 法人税、地方税の当期確定税額の計算
11
+ #
12
+ def 税額計算
13
+ 所得 = 所得金額
14
+ { houjin: {}, kenmin: {}, shimin: {} }.tap do |tax|
15
+ 法人税額 = 中小企業の軽減税額(所得) + 一般区分の税額(所得)
16
+ tax[:houjin][:kokuzei] = (法人税額 / 100).floor * 100
17
+ 地方法人税課税標準 = (法人税額 / 1000).floor * 1000
18
+ 地方法人税 = 地方法人税額(地方法人税課税標準)
19
+ tax[:houjin][:chihou] = (地方法人税 / 100).floor * 100
20
+
21
+ tax[:kenmin][:houjinzei], tax[:shimin][:houjinzei] = 法人税割(法人税額)
22
+ tax[:kenmin][:kintou], tax[:shimin][:kintou] = 均等割
23
+ tax[:kenmin][:shotoku] = 所得割400万以下(所得) + 所得割800万以下(所得) + 所得割800万超(所得)
24
+ tax[:kenmin][:tokubetsu] = 地方法人特別税(tax[:kenmin][:shotoku])
25
+ end
26
+ end
27
+
28
+ # -----------------------------------------------------
29
+ # :section: 法人税額の計算
30
+ # -----------------------------------------------------
31
+
32
+ def 中小企業の軽減税率対象所得(所得 = nil)
33
+ 所得 ||= 所得金額
34
+ return 0 if 所得 <= 0
35
+
36
+ if 所得 >= 8_000_000
37
+ 8_000_000
38
+ elsif 所得 < 0
39
+ 0
40
+ else
41
+ (所得 / 1000).floor * 1000
42
+ end
43
+ end
44
+
45
+ def 中小企業の軽減税額(所得 = nil)
46
+ 中小企業の軽減税率対象所得(所得) * 15 / 100
47
+ end
48
+
49
+ def 中小企業の軽減税率対象を超える所得(所得 = nil)
50
+ 所得 ||= 所得金額
51
+ return 0 if 所得 <= 0
52
+
53
+ if 所得 <= 8_000_000
54
+ 0
55
+ else
56
+ ((所得 - 8_000_000) / 1000).floor * 1000
57
+ end
58
+ end
59
+
60
+ def 一般区分の税額(所得 = nil)
61
+ (中小企業の軽減税率対象を超える所得(所得) * 23.2 / 100).to_i
62
+ end
63
+
64
+ def 地方法人税額(地方法人税課税標準)
65
+ (地方法人税課税標準 * 10.3 / 100).to_i
66
+ end
67
+
68
+ # 繰越損失適用後の所得金額
69
+ #
70
+ def 所得金額
71
+ @繰越損失管理 = Sonshitsu.load(@end_date).update(当期所得金額).save if @繰越損失管理.nil?
72
+ @繰越損失管理.profit
73
+ end
74
+
10
75
  # 税引前当期利益をもとに計算
11
76
  # 消費税を租税公課に計上している場合、控除済みの金額
12
- # 未払/未収事業税は精算時に認識
77
+ # 未払事業税は精算時に認識
13
78
  #
14
- def 所得金額
79
+ def 当期所得金額
15
80
  _, 納付事業税 = 未納事業税期中増減
16
- LucaSupport::Code.readable(@pl_data.dig('GA') - 納付事業税 + 還付事業税)
81
+ LucaSupport::Code.readable(@pl_data.dig('GA') - 納付事業税)
82
+ end
83
+
84
+ # -----------------------------------------------------
85
+ # :section: 繰越損失の計算
86
+ # -----------------------------------------------------
87
+
88
+ def 期首繰越損失
89
+ @繰越損失管理.records
90
+ .filter { |record| record['start_date'] > @end_date.prev_year(10) && record['end_date'] < @start_date }
91
+ .inject(0) { |sum, record| sum + (record['amount'] || 0) }
92
+ end
93
+
94
+ def 当期控除計
95
+ @繰越損失管理.deduction
96
+ end
97
+
98
+ def 翌期繰越損失
99
+ @繰越損失管理.records
100
+ .filter { |record| record['start_date'] > @end_date.prev_year(10) && record['end_date'] < @start_date }
101
+ .inject(0) { |sum, record| sum + (record['amount'] || 0) }
102
+ end
103
+
104
+ def 当期繰越損失
105
+ @繰越損失管理.records
106
+ .filter { |record| record['start_date'] == @start_date }.dig(0, 'increase') || 0
107
+ end
108
+
109
+
110
+ # -----------------------------------------------------
111
+ # :section: 地方税額の計算
112
+ # -----------------------------------------------------
113
+
114
+ def 均等割
115
+ if config.dig('jp', 'eltax', 'office_23ku')
116
+ [70_000, 0]
117
+ else
118
+ [20_000, 50_000]
119
+ end
120
+ end
121
+
122
+ def 法人税割(法人税 = nil)
123
+ 課税標準 = if 法人税
124
+ (法人税 / 1000).floor * 1000
125
+ else
126
+ @法人税割課税標準
127
+ end
128
+ if config.dig('jp', 'eltax', 'office_23ku')
129
+ [(課税標準 * 7 / 100).floor, 0]
130
+ else
131
+ [(課税標準 * 1 / 100).floor, (課税標準 * 6 / 100).floor]
132
+ end
133
+ end
134
+
135
+ def 所得400万以下(所得 = nil)
136
+ 所得 ||= 所得金額
137
+ return 0 if 所得 < 0
138
+
139
+ if 所得 >= 4_000_000
140
+ 4_000_000
141
+ else
142
+ (所得 / 1000).floor * 1000
143
+ end
144
+ end
145
+
146
+ def 所得割400万以下(所得 = nil)
147
+ ((所得400万以下(所得) * 3.5 / 100) / 100).floor * 100
148
+ end
149
+
150
+ def 所得800万以下(所得 = nil)
151
+ 所得 ||= 所得金額
152
+ return 0 if 所得 < 0
153
+
154
+ if 所得 <= 4_000_000
155
+ 0
156
+ elsif 所得 >= 8_000_000
157
+ 4_000_000
158
+ else
159
+ ((所得 - 4_000_000) / 1000).floor * 1000
160
+ end
161
+ end
162
+
163
+ def 所得割800万以下(所得 = nil)
164
+ ((所得800万以下(所得) * 5.3 / 100) / 100).floor * 100
165
+ end
166
+
167
+ def 所得800万超(所得 = nil)
168
+ 所得 ||= 所得金額
169
+ return 0 if 所得 < 0
170
+
171
+ if 所得 <= 8_000_000
172
+ 0
173
+ else
174
+ ((所得 - 8_000_000) / 1000).floor * 1000
175
+ end
176
+ end
177
+
178
+ def 所得割800万超(所得 = nil)
179
+ ((所得800万超(所得) * 7.0 / 100) / 100).floor * 100
180
+ end
181
+
182
+ def 地方法人特別税(事業税)
183
+ ((事業税 * 37 / 100) / 100).floor * 100
17
184
  end
18
185
 
19
186
  def 消費税課税売上高(税率 = 10)
@@ -37,12 +204,25 @@ module Luca
37
204
  end
38
205
 
39
206
  def 還付事業税
40
- LucaBook::State.gross(@start_date.year, @start_date.month, @end_date.year, @end_date.month, code: '1504')[:credit]
207
+ refund_tax('1504')
41
208
  end
42
209
 
43
210
  def 未納事業税期中増減
44
211
  r = LucaBook::State.gross(@start_date.year, @start_date.month, @end_date.year, @end_date.month, code: '5152')
45
- [LucaSupport::Code.readable(r[:credit] || 0), LucaSupport::Code.readable(r[:debit] || 0)]
212
+ [LucaSupport::Code.readable(r[:credit]['5152'] || 0), LucaSupport::Code.readable(r[:debit]['5152'] || 0)]
213
+ end
214
+
215
+
216
+ # -----------------------------------------------------
217
+ # :section: 消費税の計算
218
+ # -----------------------------------------------------
219
+
220
+ def 消費税中間納付額
221
+ prepaid_tax('185B')
222
+ end
223
+
224
+ def 地方消費税中間納付額
225
+ prepaid_tax('185C')
46
226
  end
47
227
  end
48
228
  end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'luca_support'
4
+ require 'luca_support/config'
5
+
6
+ module Luca
7
+ module Jp
8
+ module ItPart
9
+ # タグの出現順序は順不同ではない。eTaxの定義に準拠
10
+ #
11
+ def it_part
12
+ entries = ['<IT VR="1.4" id="IT">']
13
+ entries.concat(['zeimusho']
14
+ .map{ |key| render_it_tag(key) })
15
+ entries << teisyutsu_day
16
+ entries.concat(['nozeisha_id', 'nozeisha_bango']
17
+ .map{ |key| render_it_tag(key) })
18
+ entries.concat(['nozeisha_nm_kn', 'nozeisha_nm', 'nozeisha_zip', 'nozeisha_adr_kn', 'nozeisha_adr', 'nozeisha_tel']
19
+ .map{ |key| render_it_tag(key) })
20
+ entries.concat(['shihon_kin', 'jigyo_naiyo', 'kanpu_kinyukikan']
21
+ .map{ |key| render_it_tag(key) })
22
+ entries.concat(['daihyo_nm_kn', 'daihyo_nm', 'daihyo_zip', 'daihyo_adr', 'daihyo_tel']
23
+ .map{ |key| render_it_tag(key) })
24
+ entries << %Q(<TETSUZUKI ID="TETSUZUKI"><procedure_CD>#{@procedure_code}</procedure_CD><procedure_NM>#{@procedure_name}</procedure_NM></TETSUZUKI>)
25
+ entries.concat([jigyo_nendo_from, jigyo_nendo_to, kazei_kikan_from, kazei_kikan_to])
26
+ entries << render_it_tag('keiri_sekininsha')
27
+ entries << '<SHINKOKU_KBN ID="SHINKOKU_KBN"><kubun_CD>1</kubun_CD></SHINKOKU_KBN>'
28
+ entries.concat(['eltax_id'].map{ |key| render_it_tag(key) })
29
+ entries << '</IT>'
30
+ entries.compact.join("\n")
31
+ end
32
+
33
+ def render_it_tag(key)
34
+ content = config.dig('jp', 'it_part', key)
35
+ return nil if content.nil?
36
+
37
+ case key
38
+ when 'zeimusho'
39
+ content = parse_zeimusho(content)
40
+ when 'nozeisha_tel', 'daihyo_tel'
41
+ content = parse_tel(content)
42
+ when 'nozeisha_zip', 'daihyo_zip'
43
+ content = parse_zip(content)
44
+ when 'nozeisha_bango'
45
+ content = parse_houjinbango(content)
46
+ when 'kanpu_kinyukikan'
47
+ content = parse_kinyukikan(content)
48
+ end
49
+
50
+ tag = key.to_s.upcase
51
+ %Q(<#{tag} ID="#{tag}">#{content}</#{tag}>)
52
+ end
53
+
54
+ def parse_zeimusho(str)
55
+ items = str.split('-')
56
+ %Q(<gen:zeimusho_CD>#{items[0]}</gen:zeimusho_CD><gen:zeimusho_NM>#{items[1]}</gen:zeimusho_NM>)
57
+ end
58
+
59
+ def parse_houjinbango(str)
60
+ %Q(<gen:hojinbango>#{str}</gen:hojinbango>)
61
+ end
62
+
63
+ def parse_kinyukikan(str)
64
+ items = str.split('-')
65
+ %Q(<gen:kinyukikan_NM kinyukikan_KB="1">#{items[0]}</gen:kinyukikan_NM><gen:shiten_NM shiten_KB="2">#{items[1]}</gen:shiten_NM><gen:yokin>#{items[2]}</gen:yokin><gen:koza>#{items[3]}</gen:koza>)
66
+ end
67
+
68
+ def parse_tel(str)
69
+ num = str.split('-')
70
+ %Q(<gen:tel1>#{num[0]}</gen:tel1><gen:tel2>#{num[1]}</gen:tel2><gen:tel3>#{num[2]}</gen:tel3>)
71
+ end
72
+
73
+ def parse_zip(str)
74
+ num = str.split('-')
75
+ %Q(<gen:zip1>#{num[0]}</gen:zip1><gen:zip2>#{num[1]}</gen:zip2>)
76
+ end
77
+
78
+ def teisyutsu_day
79
+ %Q(<TEISYUTSU_DAY ID="TEISYUTSU_DAY"><gen:era>#{gengou(@issue_date)}</gen:era><gen:yy>#{wareki(@issue_date)}</gen:yy><gen:mm>#{@issue_date.month}</gen:mm><gen:dd>#{@issue_date.day}</gen:dd></TEISYUTSU_DAY>)
80
+ end
81
+
82
+ def jigyo_nendo_from
83
+ %Q(<JIGYO_NENDO_FROM ID="JIGYO_NENDO_FROM"><gen:era>#{gengou(@start_date)}</gen:era><gen:yy>#{wareki(@start_date)}</gen:yy><gen:mm>#{@start_date.month}</gen:mm><gen:dd>#{@start_date.day}</gen:dd></JIGYO_NENDO_FROM>)
84
+ end
85
+
86
+ def jigyo_nendo_to
87
+ %Q(<JIGYO_NENDO_TO ID="JIGYO_NENDO_TO"><gen:era>#{gengou(@end_date)}</gen:era><gen:yy>#{wareki(@end_date)}</gen:yy><gen:mm>#{@end_date.month}</gen:mm><gen:dd>#{@end_date.day}</gen:dd></JIGYO_NENDO_TO>)
88
+ end
89
+
90
+ def kazei_kikan_from
91
+ %Q(<KAZEI_KIKAN_FROM ID="KAZEI_KIKAN_FROM"><gen:era>#{gengou(@start_date)}</gen:era><gen:yy>#{wareki(@start_date)}</gen:yy><gen:mm>#{@start_date.month}</gen:mm><gen:dd>#{@start_date.day}</gen:dd></KAZEI_KIKAN_FROM>)
92
+ end
93
+
94
+ def kazei_kikan_to
95
+ %Q(<KAZEI_KIKAN_TO ID="KAZEI_KIKAN_TO"><gen:era>#{gengou(@end_date)}</gen:era><gen:yy>#{wareki(@end_date)}</gen:yy><gen:mm>#{@end_date.month}</gen:mm><gen:dd>#{@end_date.day}</gen:dd></KAZEI_KIKAN_TO>)
96
+ end
97
+ end
98
+ end
99
+ end