luca-jp 0.1.1 → 0.1.6

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.
@@ -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