luca-jp 0.1.3 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -24,8 +24,9 @@ module Luca
24
24
  @issue_date = Date.today
25
25
  @company = CGI.escapeHTML(config.dig('company', 'name'))
26
26
  @software = 'LucaJp'
27
- @jimusho_code = config.dig('jp', 'eltax', 'jimusho_code')
28
- @jimusho_name = '都税事務所長'
27
+ @jimusho_code = eltax_config('jimusho_code')
28
+ @jimusho_name = eltax_config('jimusho_name')
29
+ @app_version = eltax_config('app_version')
29
30
 
30
31
  @税額 = 税額計算
31
32
  @均等割 = @税額.dig(:kenmin, :kintou)
@@ -62,9 +63,9 @@ module Luca
62
63
  else
63
64
  @procedure_code = 'R0102100'
64
65
  @procedure_name = '法人都道府県民税・事業税・特別法人事業税又は地方法人特別税 確定申告'
65
- @form_sec = ['R0102AA190', 'R0102AG120'].map{ |c| form_attr(c) }.join('')
66
- @user_inf = render_erb(search_template('el-userinf.xml.erb'))
67
- @form_data = [第六号, 別表四三].join("\n")
66
+ @form_sec = ['R0102AA190', 'R0102AG120', 別表九フォーム].compact.map{ |c| form_attr(c) }.join('')
67
+ @user_inf = render_erb(search_template('eltax-userinf.xml.erb'))
68
+ @form_data = [第六号, 別表四三, 別表九].compact.join("\n")
68
69
  render_erb(search_template('eltax.xml.erb'))
69
70
  end
70
71
  end
@@ -81,22 +82,22 @@ module Luca
81
82
  item['credit'] << { 'label' => karibarai_label(k), 'amount' => dat[:chukan] }
82
83
  end
83
84
  if dat[:chukan] > dat[:zeigaku]
84
- item['debit'] << { 'label' => '未収法人税', 'amount' => dat[:chukan] - dat[:zeigaku] }
85
+ item['debit'] << { 'label' => '未収地方事業税', 'amount' => dat[:chukan] - dat[:zeigaku] }
85
86
  else
86
87
  item['credit'] << { 'label' => '未払地方事業税', 'amount' => dat[:zeigaku] - dat[:chukan] }
87
88
  end
88
- item['debit'] << { 'label' => '法人税、住民税及び事業税', 'amount' => dat[:zeigaku] }
89
+ item['debit'] << { 'label' => '法人税、住民税及び事業税', 'amount' => dat[:zeigaku] } if dat[:zeigaku] > 0
89
90
  end
90
91
  records[:juminzei].each do |k, dat|
91
92
  if dat[:chukan] > 0
92
93
  item['credit'] << { 'label' => karibarai_label(k), 'amount' => dat[:chukan] }
93
94
  end
94
95
  if dat[:chukan] > dat[:zeigaku]
95
- item['debit'] << { 'label' => '未収法人税', 'amount' => dat[:chukan] - dat[:zeigaku] }
96
+ item['debit'] << { 'label' => '未収都道府県住民税', 'amount' => dat[:chukan] - dat[:zeigaku] }
96
97
  else
97
98
  item['credit'] << { 'label' => '未払都道府県民税', 'amount' => dat[:zeigaku] - dat[:chukan] }
98
99
  end
99
- item['debit'] << { 'label' => '法人税、住民税及び事業税', 'amount' => dat[:zeigaku] }
100
+ item['debit'] << { 'label' => '法人税、住民税及び事業税', 'amount' => dat[:zeigaku] } if dat[:zeigaku] > 0
100
101
  end
101
102
  item['x-editor'] = 'LucaJp'
102
103
  res << item
@@ -105,6 +106,7 @@ module Luca
105
106
  end
106
107
 
107
108
  def 第六号
109
+ @資本金準備金 = eltax_config('shihon') || it_part_config('shihon_kin')
108
110
  render_erb(search_template('el-no6.xml.erb'))
109
111
  end
110
112
 
@@ -113,19 +115,76 @@ module Luca
113
115
  render_erb(search_template('el-no6-43.xml.erb'))
114
116
  end
115
117
 
118
+ def 別表九フォーム
119
+ return nil if @繰越損失管理.records.length == 0
120
+
121
+ 'R0102AM190'
122
+ end
123
+
124
+ def 別表九
125
+ return nil if @繰越損失管理.records.length == 0
126
+
127
+ render_erb(search_template('el-no6-9.xml.erb'))
128
+ end
129
+
116
130
  private
117
131
 
118
132
  def 法人税割課税標準
119
- national_tax = Luca::Jp::Aoiro.range(@start_date.year, @start_date.month, @end_date.year, @end_date.month).kani(export: true)
120
- (national_tax[:kokuzei][:zeigaku] / 1000).floor * 1000
133
+ (@税額.dig(:houjin, :kokuzei) / 1000).floor * 1000
121
134
  end
122
135
 
123
136
  def 事業税中間納付
124
137
  @所得割中間納付
125
138
  end
126
139
 
140
+ # TODO: 損失の区分
141
+ #
142
+ def 別表九各期青色損失
143
+ tags = @繰越損失管理.records
144
+ .filter { |record| record['start_date'] > @end_date.prev_year(10) && record['end_date'] < @start_date }
145
+ .map do |record|
146
+ deduction = record['decrease']&.filter{ |r| r['date'] >= @start_date }&.dig(0, 'val') || 0
147
+ next if deduction == 0 && record['amount'] == 0
148
+
149
+ %Q(<AMB00200>
150
+ <AMB00210>#{etax_date(@start_date)}</AMB00210>
151
+ <AMB00220>#{etax_date(@end_date)}</AMB00220>
152
+ <AMB00225 />
153
+ #{render_attr('AMB00230', deduction + record['amount'])}
154
+ #{render_attr('AMB00240', deduction)}
155
+ #{render_attr('AMB00250', record['amount'])}
156
+ </AMB00200>)
157
+ end
158
+ return tags.compact.join("\n") if tags.length > 0
159
+
160
+ %Q(<AMB00200>
161
+ <AMB00210><gen:era /><gen:yy /><gen:mm /><gen:dd /></AMB00210>
162
+ <AMB00220><gen:era /><gen:yy /><gen:mm /><gen:dd /></AMB00220>
163
+ <AMB00225 />
164
+ <AMB00230 />
165
+ <AMB00240 />
166
+ <AMB00250 />
167
+ </AMB00200>)
168
+ end
169
+
170
+ def eltax_kouza
171
+ items = it_part_config('kanpu_kinyukikan').split('-')
172
+ %Q(<gen:kubun_CD />
173
+ <gen:kinyukikan_NM>#{items[0]}</gen:kinyukikan_NM>
174
+ <gen:shiten_NM>#{items[1]}</gen:shiten_NM>
175
+ <gen:kinyukikan_CD />
176
+ <gen:shiten_CD />
177
+ <gen:yokin>1</gen:yokin>
178
+ <gen:koza>#{items[3]}</gen:koza>)
179
+ end
180
+
127
181
  def form_attr(code)
128
- "<FORM_ATTR><FORM_ID>#{code}</FORM_ID><FORM_NAME></FORM_NAME><FORM_FILE_NAME></FORM_FILE_NAME><FORM_XSL_NAME></FORM_XSL_NAME></FORM_ATTR>"
182
+ name = {
183
+ 'R0102AA' => '中間・確定申告書',
184
+ 'R0102AG' => '均等割額の計算に関する明細書',
185
+ 'R0102AM' => '欠損金額等及び災害損失金の控除明細書'
186
+ }[code[0,7]]
187
+ "<FORM_ATTR><FORM_ID>#{code}</FORM_ID><FORM_NAME>#{name}</FORM_NAME><FORM_FILE_NAME></FORM_FILE_NAME><FORM_XSL_NAME></FORM_XSL_NAME></FORM_ATTR>"
129
188
  end
130
189
 
131
190
  def karibarai_label(key)
@@ -140,7 +199,7 @@ module Luca
140
199
  '仮払地方税資本割'
141
200
  when :fukakachi
142
201
  '仮払地方税付加価値割'
143
- when :hojinzei
202
+ when :houjinzei
144
203
  '仮払地方税法人税割'
145
204
  when :kinto
146
205
  '仮払地方税均等割'
@@ -31,6 +31,8 @@ module Luca
31
31
 
32
32
  def 中小企業の軽減税率対象所得(所得 = nil)
33
33
  所得 ||= 所得金額
34
+ return 0 if 所得 <= 0
35
+
34
36
  if 所得 >= 8_000_000
35
37
  8_000_000
36
38
  elsif 所得 < 0
@@ -41,11 +43,13 @@ module Luca
41
43
  end
42
44
 
43
45
  def 中小企業の軽減税額(所得 = nil)
44
- 中小企業の軽減税率対象所得(所得) * 15 / 100
46
+ 中小企業の軽減税率対象所得(所得) * 15 / 100
45
47
  end
46
48
 
47
49
  def 中小企業の軽減税率対象を超える所得(所得 = nil)
48
50
  所得 ||= 所得金額
51
+ return 0 if 所得 <= 0
52
+
49
53
  if 所得 <= 8_000_000
50
54
  0
51
55
  else
@@ -61,15 +65,48 @@ module Luca
61
65
  (地方法人税課税標準 * 10.3 / 100).to_i
62
66
  end
63
67
 
68
+ # 繰越損失適用後の所得金額
69
+ #
70
+ def 所得金額
71
+ @繰越損失管理 = Sonshitsu.load(@end_date).update(当期所得金額).save if @繰越損失管理.nil?
72
+ @繰越損失管理.profit
73
+ end
74
+
64
75
  # 税引前当期利益をもとに計算
65
76
  # 消費税を租税公課に計上している場合、控除済みの金額
66
- # 未払/未収事業税は精算時に認識
77
+ # 未払事業税は精算時に認識
67
78
  #
68
- def 所得金額
79
+ def 当期所得金額
69
80
  _, 納付事業税 = 未納事業税期中増減
70
- 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
71
107
  end
72
108
 
109
+
73
110
  # -----------------------------------------------------
74
111
  # :section: 地方税額の計算
75
112
  # -----------------------------------------------------
@@ -97,6 +134,8 @@ module Luca
97
134
 
98
135
  def 所得400万以下(所得 = nil)
99
136
  所得 ||= 所得金額
137
+ return 0 if 所得 < 0
138
+
100
139
  if 所得 >= 4_000_000
101
140
  4_000_000
102
141
  else
@@ -110,6 +149,8 @@ module Luca
110
149
 
111
150
  def 所得800万以下(所得 = nil)
112
151
  所得 ||= 所得金額
152
+ return 0 if 所得 < 0
153
+
113
154
  if 所得 <= 4_000_000
114
155
  0
115
156
  elsif 所得 >= 8_000_000
@@ -125,6 +166,8 @@ module Luca
125
166
 
126
167
  def 所得800万超(所得 = nil)
127
168
  所得 ||= 所得金額
169
+ return 0 if 所得 < 0
170
+
128
171
  if 所得 <= 8_000_000
129
172
  0
130
173
  else
@@ -161,12 +204,25 @@ module Luca
161
204
  end
162
205
 
163
206
  def 還付事業税
164
- LucaBook::State.gross(@start_date.year, @start_date.month, @end_date.year, @end_date.month, code: '1504')[:credit]
207
+ refund_tax('1504')
165
208
  end
166
209
 
167
210
  def 未納事業税期中増減
168
211
  r = LucaBook::State.gross(@start_date.year, @start_date.month, @end_date.year, @end_date.month, code: '5152')
169
- [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')
170
226
  end
171
227
  end
172
228
  end
@@ -24,7 +24,7 @@ module Luca
24
24
  entries << %Q(<TETSUZUKI ID="TETSUZUKI"><procedure_CD>#{@procedure_code}</procedure_CD><procedure_NM>#{@procedure_name}</procedure_NM></TETSUZUKI>)
25
25
  entries.concat([jigyo_nendo_from, jigyo_nendo_to, kazei_kikan_from, kazei_kikan_to])
26
26
  entries << render_it_tag('keiri_sekininsha')
27
- entries << '<SHINKOKU_KBN ID="SHINKOKU_KBN"><kubun_CD>1</kubun_CD></SHINKOKU_KBN>'
27
+ entries << '<SHINKOKU_KBN ID="SHINKOKU_KBN"><kubun_CD>30</kubun_CD></SHINKOKU_KBN>'
28
28
  entries.concat(['eltax_id'].map{ |key| render_it_tag(key) })
29
29
  entries << '</IT>'
30
30
  entries.compact.join("\n")
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'date'
4
+ require 'pathname'
5
+ require 'yaml'
6
+ require 'luca_book'
7
+ require 'luca_support/config'
8
+
9
+ module Luca
10
+ module Jp
11
+ # 青色申告に基く繰越損失の計算
12
+ #
13
+ class Sonshitsu
14
+ # 当期控除額
15
+ attr_reader :deduction
16
+ # 控除後所得
17
+ attr_reader :profit
18
+ # 各期繰越損失
19
+ attr_reader :records
20
+
21
+ def initialize(records, date)
22
+ @records = records
23
+ @report_date = date
24
+ net_amount
25
+ @deduction = 0
26
+ @profit = 0
27
+ end
28
+
29
+ # sonshitsu format is as bellows:
30
+ #
31
+ # - start_date: 2020-01-01
32
+ # end_date: 2020-12-31
33
+ # increase: 1000000
34
+ # - start_date: 2021-01-01
35
+ # end_date: 2021-12-31
36
+ # decrease: 800000
37
+ #
38
+ def self.load(this_year)
39
+ records = if File.exist?(record_file)
40
+ YAML.load_file(record_file)
41
+ .filter { |record| record['start_date'] > this_year.prev_year(11) && record['end_date'] < this_year }
42
+ .sort { |a, b| a['start_date'] <=> b['start_date'] }
43
+ else
44
+ []
45
+ end
46
+ new(records, this_year)
47
+ end
48
+
49
+ def save
50
+ File.open(self.class.record_file, 'w') { |f| f.puts YAML.dump(@records)}
51
+ self
52
+ end
53
+
54
+ def update(profit_or_loss)
55
+ return self if profit_or_loss == 0
56
+
57
+ if profit_or_loss < 0
58
+ start_date, end_date = LucaBook::Util.current_fy(@report_date)
59
+ @records << {
60
+ 'start_date' => start_date,
61
+ 'end_date' => end_date,
62
+ 'increase' => profit_or_loss.abs
63
+ }
64
+ @profit = profit_or_loss
65
+ return self
66
+ end
67
+
68
+ @records.each do |record|
69
+ next if profit_or_loss <= 0
70
+ next if record['amount'] <= 0
71
+
72
+ decrease_amount = [record['amount'], profit_or_loss].min
73
+ record['decrease'] ||= []
74
+ record['decrease'] << { 'date' => @report_date, 'val' => decrease_amount }
75
+ record['amount'] -= decrease_amount
76
+ profit_or_loss -= decrease_amount
77
+ @deduction += decrease_amount
78
+ end
79
+ @profit = profit_or_loss
80
+ self
81
+ end
82
+
83
+ def net_amount
84
+ @records.each do |record|
85
+ record['amount'] = record['increase'] - past_decreased(record['decrease'])
86
+ record['decrease'] = record['decrease']&.reject { |decrease_record| decrease_record['date'] > @report_date.prev_year }
87
+ end
88
+ end
89
+
90
+ def past_decreased(decrease_records)
91
+ return 0 if decrease_records.nil?
92
+
93
+ decrease_records.filter { |record| record['date'] <= @report_date.prev_year }
94
+ .map { |record| record['val'] }.sum || 0
95
+ end
96
+
97
+ def self.record_file
98
+ Pathname(LucaSupport::PJDIR) / 'data' / 'balance' / 'sonshitsu.yml'
99
+ end
100
+ end
101
+ end
102
+ end
@@ -12,6 +12,7 @@ module Luca
12
12
  module Jp
13
13
  class Syouhizei < LucaBook::State
14
14
  include LucaSupport::View
15
+ include Luca::Jp::ItPart
15
16
  include Luca::Jp::Util
16
17
 
17
18
  @dirname = 'journals'
@@ -33,8 +34,8 @@ module Luca
33
34
  @みなし仕入税額 = (@tax_amount * みなし仕入率(config.dig('jp', 'syouhizei_kubun')) / 100).floor
34
35
  @税額 = LucaSupport::Code.readable(((@tax_amount - @みなし仕入税額) / 100).floor * 100)
35
36
  @譲渡割額 = (@税額 * 地方税率 / (税率*100)).floor * 100
36
- @中間納付額 = prepaid_tax('185B')
37
- @地方税中間納付額 = prepaid_tax('185C')
37
+ @中間納付額 = 消費税中間納付額
38
+ @地方税中間納付額 = 地方消費税中間納付額
38
39
 
39
40
  if export
40
41
  {
@@ -44,11 +44,13 @@
44
44
  <%= render_attr('BGB00200', @法人税中間納付) %>
45
45
  <%= render_attr('BGB00210', 納付税額(@確定法人税額, @法人税中間納付)) %>
46
46
  <BGB00320>
47
- <%= render_attr('BGB00340', 中間還付税額(@確定法人税額, @法人税中間納付)) %>
47
+ <%= render_attr('BGB00340', 中間還付税額(@確定法人税額, @法人税中間納付)) %>
48
48
  <BGB00380>
49
49
  <%= render_attr('BGB00400', 中間還付税額(@確定法人税額, @法人税中間納付)) %>
50
50
  </BGB00380>
51
51
  </BGB00320>
52
+ <%= render_attr('BGB00460', 当期控除計) %>
53
+ <%= render_attr('BGB00470', 翌期繰越損失 + 当期繰越損失) %>
52
54
  </BGB00000>
53
55
  <BGC00000>
54
56
  <BGC00010>
@@ -6,4 +6,35 @@
6
6
  </VAA00010>
7
7
  <VAA00040 IDREF="NOZEISHA_NM"/>
8
8
  </VAA00000>
9
+ <VAB00000>
10
+ <%= render_attr('VAB00010', beppyo2_config('total_shares')) %>
11
+ <%= render_attr('VAB00020', 別表二上位株数) %>
12
+ <%= render_attr('VAB00030', 別表二上位株割合) %>
13
+ <VAB00040>
14
+ <%= render_attr('VAB00060', beppyo2_config('total_votes')) %>
15
+ </VAB00040>
16
+ <%= render_attr('VAB00070', 別表二上位議決権数) %>
17
+ <%= render_attr('VAB00080', 別表二上位議決権割合) %>
18
+ </VAB00000>
19
+ <VAE00000>
20
+ <VAE00010>
21
+ <VAE00020>
22
+ <VAE00030>1</VAE00030>
23
+ <VAE00040>1</VAE00040>
24
+ </VAE00020>
25
+ <VAE00050>
26
+ <%= render_attr('VAE00060', beppyo2_config('owners')&.dig(0, 'address')) %>
27
+ <%= render_attr('VAE00070', beppyo2_config('owners')&.dig(0, 'name')) %>
28
+ </VAE00050>
29
+ <VAE00080>
30
+ <VAE00120>
31
+ <%= render_attr('VAE00130', beppyo2_config('owners')&.dig(0, 'shares')) %>
32
+ <VAE00140>
33
+ <%= render_attr('VAE00160', beppyo2_config('owners')&.dig(0, 'votes')) %>
34
+ </VAE00140>
35
+ </VAE00120>
36
+ </VAE00080>
37
+ </VAE00010>
38
+ <%= 別表二株主リスト %>
39
+ </VAE00000>
9
40
  </HOA201>