luca-jp 0.1.3 → 0.1.8

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