lucabook 0.2.17 → 0.2.22

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5b204a2ed70889d0750a6883de424ceb3b7e335cce99262eb98e288db6962cbd
4
- data.tar.gz: e19db20331a4edce1ea02ffb47495c3f849f74ba0bf78b13c7cf0562207fc0d2
3
+ metadata.gz: 4755b2574729e35ae914dd92338ed007df2e1158d49c613613cac3b42423c6ee
4
+ data.tar.gz: a559a270322897b10b6dae569102f028004221431300debe19f3d0e5ae6432fe
5
5
  SHA512:
6
- metadata.gz: 16800a60362abcc56adb26ed60611a98a5ec5c3545143b4a0c4a379aac3988952e733dac19bf5c2188ce9e7c244dff1b4d6269635a226eeda51ec85c4ab2178f
7
- data.tar.gz: f60f61de1a1c18df3db8c1bc5278ae084089137b15ee88f198ff17c6418917c6adebb634820dcd9979b42a9ecf7e902329c7bb14fb950f5270154492a2b0d8b2
6
+ metadata.gz: 34b28c364e41ddecf9296ef39130897f03228e0bb0184241e0a7fce4349d41b14ff0ea72318154eb0bfa5e8fdac401783851c61e34e3419620eac6ab12cf6b05
7
+ data.tar.gz: 1bbd862143cc37ba7c459a6d3fae832bbdad744b1db6afc3956175fa97660a1decf8a778c6c40c3e276dd35272ed363f5d9e575ce555b73a368cf2ef8173fcbf
@@ -1,10 +1,11 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
+ require 'json'
3
4
  require 'optparse'
4
5
  require 'luca_book'
5
6
 
6
- module LucaCmd
7
- class Journal
7
+ class LucaCmd
8
+ class Journal < LucaCmd
8
9
  def self.import(args, params)
9
10
  if params['config']
10
11
  LucaBook::Import.new(args[0], params['config']).import_csv
@@ -12,33 +13,59 @@ module LucaCmd
12
13
  LucaBook::Import.import_json(STDIN.read)
13
14
  else
14
15
  puts 'Usage: luca-book import -c import_config'
16
+ exit 1
15
17
  end
16
18
  end
17
19
 
18
20
  def self.list(args, params)
21
+ args = gen_range(params[:n] || 1) if args.empty?
19
22
  if params['code']
20
- LucaBook::List.term(*args, code: params['code']).list_on_code.to_yaml
21
- elsif args.length > 0
22
- LucaBook::List.term(*args).list_journals.to_yaml
23
+ render(LucaBook::List.term(*args, code: params['code']).list_on_code, params)
23
24
  else
24
- # TODO: define default function
25
+ render(LucaBook::List.term(*args).list_journals, params)
25
26
  end
26
27
  end
27
28
 
28
29
  def self.stats(args, params)
29
- LucaBook::State.term(*args).stats(params[:level])
30
+ args = gen_range(params[:n]) if args.empty?
31
+ if params['code']
32
+ render(LucaBook::State.by_code(params['code'], *args), params)
33
+ else
34
+ render(LucaBook::State.range(*args).stats(params[:level]), params)
35
+ end
30
36
  end
31
37
  end
32
38
 
33
- class Report
39
+ class Report < LucaCmd
34
40
  def self.balancesheet(args, params)
35
- level = params[:level] || 2
41
+ level = params[:level] || 3
36
42
  legal = params[:legal] || false
37
- LucaBook::State.term(*args).bs(level, legal: legal)
43
+ args = gen_range(params[:n] || 1) if args.empty?
44
+ render(LucaBook::State.range(*args).bs(level, legal: legal), params)
38
45
  end
39
46
 
40
47
  def self.profitloss(args, params)
41
- LucaBook::State.term(*args).pl.to_yaml
48
+ level = params[:level] || 2
49
+ args = gen_range(params[:n]) if args.empty?
50
+ render(LucaBook::State.range(*args).pl(level), params)
51
+ end
52
+ end
53
+
54
+ def self.gen_range(count)
55
+ count ||= 3
56
+ today = Date.today
57
+ start = today.prev_month(count - 1)
58
+ [start.year, start.month, today.year, today.month]
59
+ end
60
+
61
+ def self.render(dat, params)
62
+ case params[:output]
63
+ when 'json'
64
+ puts JSON.dump(dat)
65
+ when 'nu'
66
+ LucaSupport::View.nushell(YAML.dump(dat))
67
+ else
68
+ puts YAML.dump(dat)
42
69
  end
43
70
  end
44
71
  end
@@ -57,7 +84,7 @@ when /journals?/, 'j'
57
84
  case subcmd
58
85
  when 'import'
59
86
  OptionParser.new do |opt|
60
- opt.banner = 'Usage: luca-book journals import filepath'
87
+ opt.banner = 'Usage: luca-book journals import [options] filepath'
61
88
  opt.on('-c', '--config VAL', 'import definition'){ |v| params['config'] = v }
62
89
  opt.on('-j', '--json', 'import via json format'){ |_v| params['json'] = true }
63
90
  args = opt.parse!(ARGV)
@@ -65,23 +92,37 @@ when /journals?/, 'j'
65
92
  end
66
93
  when 'list'
67
94
  OptionParser.new do |opt|
68
- opt.banner = 'Usage: luca-book journals list [year month]'
95
+ opt.banner = 'Usage: luca-book journals list [options] [YYYY M]'
69
96
  opt.on('-c', '--code VAL', 'search with code') { |v| params['code'] = v }
97
+ opt.on('-n VAL', 'report count') { |v| params[:n] = v.to_i }
98
+ opt.on('--nu', 'show table in nushell') { |_v| params[:output] = 'nu' }
99
+ opt.on('-o', '--output VAL', 'output serialized data') { |v| params[:output] = v }
70
100
  opt.on_tail('List records. If you specify code and/or month, search on each criteria.')
71
101
  args = opt.parse!(ARGV)
72
102
  LucaCmd::Journal.list(args, params)
73
103
  end
74
104
  when 'stats'
75
105
  OptionParser.new do |opt|
76
- opt.banner = 'Usage: luca-book reports bs'
77
- opt.on('-l', '--level VAL', 'account level') { |v| params[:level] = v.to_i }
106
+ opt.banner = 'Usage: luca-book journals stats [options] [YYYY M]'
107
+ opt.on('-c', '--code VAL', 'search with code') { |v| params['code'] = v }
108
+ opt.on('-n VAL', 'report count') { |v| params[:n] = v.to_i }
109
+ opt.on('--nu', 'show table in nushell') { |_v| params[:output] = 'nu' }
110
+ opt.on('-o', '--output VAL', 'output serialized data') { |v| params[:output] = v }
78
111
  args = opt.parse!(ARGV)
79
112
  LucaCmd::Journal.stats(args, params)
80
113
  end
114
+ else
115
+ puts 'Proper subcommand needed.'
116
+ puts
117
+ puts 'Usage: luca-book (j|journal[s]) subcommand [options] [YYYY M YYYY M]'
118
+ puts ' import: import journals from JSON/TSV'
119
+ puts ' list: list journals'
120
+ puts ' stats: list account statistics'
121
+ exit 1
81
122
  end
82
123
  when 'new'
83
124
  OptionParser.new do |opt|
84
- opt.banner = 'Usage: luca-book new Dir'
125
+ opt.banner = 'Usage: luca-book new [options] Dir'
85
126
  opt.on('-c', '--country VAL', 'specify country code') { |v| params['coountry'] = v }
86
127
  args = opt.parse(ARGV)
87
128
  new_pj(args, params)
@@ -91,23 +132,37 @@ when /reports?/, 'r'
91
132
  case subcmd
92
133
  when 'bs'
93
134
  OptionParser.new do |opt|
94
- opt.banner = 'Usage: luca-book reports bs'
135
+ opt.banner = 'Usage: luca-book reports bs [options] [YYYY M]'
95
136
  opt.on('-l', '--level VAL', 'account level') { |v| params[:level] = v.to_i }
96
137
  opt.on('--legal', 'show legal mandatory account') { |_v| params[:legal] = true }
138
+ opt.on('--nu', 'show table in nushell') { |_v| params[:output] = 'nu' }
139
+ opt.on('-o', '--output VAL', 'output serialized data') { |v| params[:output] = v }
97
140
  args = opt.parse!(ARGV)
98
141
  LucaCmd::Report.balancesheet(args, params)
99
142
  end
100
143
  when 'pl'
101
144
  OptionParser.new do |opt|
102
- opt.banner = 'Usage: luca-book reports pl'
145
+ opt.banner = 'Usage: luca-book reports pl [options] [YYYY M YYYY M]'
146
+ opt.on('-l', '--level VAL', 'account level') { |v| params[:level] = v.to_i }
147
+ opt.on('-n VAL', 'report count') { |v| params[:n] = v.to_i }
148
+ opt.on('--nu', 'show table in nushell') { |_v| params[:output] = 'nu' }
149
+ opt.on('-o', '--output VAL', 'output serialized data') { |v| params[:output] = v }
103
150
  args = opt.parse!(ARGV)
104
151
  LucaCmd::Report.profitloss(args, params)
105
152
  end
153
+ else
154
+ puts 'Proper subcommand needed.'
155
+ puts
156
+ puts 'Usage: luca-book (r|report[s]) (bs|pl) [options] YYYY M'
157
+ puts ' bs: show balance sheet'
158
+ puts ' pl: show statement of income'
159
+ exit 1
106
160
  end
107
- when '--help'
108
- puts 'Usage: luca-book subcommand'
161
+ else
162
+ puts 'Proper subcommand needed.'
163
+ puts
164
+ puts 'Usage: luca-book (j[ournals]|r[eports]) subcommand'
109
165
  puts ' journals: operate journal records'
110
166
  puts ' reports: show reports'
111
- else
112
- puts 'Invalid subcommand'
167
+ exit 1
113
168
  end
@@ -7,6 +7,83 @@ require 'pathname'
7
7
 
8
8
  module LucaBook
9
9
  class Dict < LucaRecord::Dict
10
+ # Column number settings for CSV/TSV convert
11
+ #
12
+ # :label
13
+ # for double entry data
14
+ # :counter_label
15
+ # must be specified with label
16
+ # :debit_label
17
+ # for double entry data
18
+ # * debit_value
19
+ # :credit_label
20
+ # for double entry data
21
+ # * credit_value
22
+ # :note
23
+ # can be the same column as another label
24
+ #
25
+ # :encoding
26
+ # file encoding
27
+ #
28
+ def csv_config
29
+ {}.tap do |config|
30
+ if @config.dig('label')
31
+ config[:label] = @config['label'].to_i
32
+ if @config.dig('counter_label')
33
+ config[:counter_label] = @config['counter_label']
34
+ config[:type] = 'single'
35
+ end
36
+ elsif @config.dig('debit_label')
37
+ config[:debit_label] = @config['debit_label'].to_i
38
+ if @config.dig('credit_label')
39
+ config[:credit_label] = @config['credit_label'].to_i
40
+ config[:type] = 'double'
41
+ end
42
+ end
43
+ config[:type] ||= 'invalid'
44
+ config[:debit_value] = @config['debit_value'].to_i if @config.dig('debit_value')
45
+ config[:credit_value] = @config['credit_value'].to_i if @config.dig('credit_value')
46
+ config[:note] = @config['note'] if @config.dig('note')
47
+ config[:encoding] = @config['encoding'] if @config.dig('encoding')
48
+
49
+ config[:year] = @config['year'] if @config.dig('year')
50
+ config[:month] = @config['month'] if @config.dig('month')
51
+ config[:day] = @config['day'] if @config.dig('day')
52
+ config[:default_debit] = @config['default_debit'] if @config.dig('default_debit')
53
+ config[:default_credit] = @config['default_credit'] if @config.dig('default_credit')
54
+ end
55
+ end
56
+
57
+ def search(word, default_word = nil, amount = nil)
58
+ res = super(word, default_word, main_key: 'account_label')
59
+ if res.is_a?(Array) && res[0].is_a?(Array)
60
+ filter_amount(res, amount)
61
+ else
62
+ res
63
+ end
64
+ end
65
+
66
+ # Choose setting on Big or small condition.
67
+ #
68
+ def filter_amount(settings, amount = nil)
69
+ return settings[0] if amount.nil?
70
+
71
+ settings.each do |item|
72
+ return item unless item[1].keys.include?(:on_amount)
73
+
74
+ condition = item.dig(1, :on_amount)
75
+ case condition[0]
76
+ when '>'
77
+ return item if amount > BigDecimal(condition[1..])
78
+ when '<'
79
+ return item if amount < BigDecimal(condition[1..])
80
+ else
81
+ return item
82
+ end
83
+ end
84
+ nil
85
+ end
86
+
10
87
  def self.latest_balance
11
88
  dict_dir = Pathname(LucaSupport::Config::Pjdir) / 'data' / 'balance'
12
89
  # TODO: search latest balance dictionary
@@ -4,9 +4,14 @@ require 'date'
4
4
  require 'json'
5
5
  require 'luca_book'
6
6
  require 'luca_support'
7
- #require 'luca_book/dict'
8
7
  require 'luca_record'
9
8
 
9
+ begin
10
+ require "luca_book/import_#{LucaSupport::CONFIG['country']}"
11
+ rescue LoadError => e
12
+ e.message
13
+ end
14
+
10
15
  module LucaBook
11
16
  class Import
12
17
  DEBIT_DEFAULT = '10XX'
@@ -18,7 +23,7 @@ module LucaBook
18
23
  @target_file = path
19
24
  # TODO: yaml need to be configurable
20
25
  @dict_name = dict
21
- @dict = LucaRecord::Dict.new("import-#{dict}.yaml")
26
+ @dict = LucaBook::Dict.new("import-#{dict}.yaml")
22
27
  @code_map = LucaRecord::Dict.reverse(LucaRecord::Dict.load('base.tsv'))
23
28
  @config = @dict.csv_config if dict
24
29
  end
@@ -45,8 +50,6 @@ module LucaBook
45
50
  #
46
51
  def self.import_json(io)
47
52
  JSON.parse(io).each do |d|
48
- validate(d)
49
-
50
53
  code_map = LucaRecord::Dict.reverse(LucaRecord::Dict.load('base.tsv'))
51
54
  d['debit'].each { |h| h['code'] = code_map.dig(h['label']) || DEBIT_DEFAULT }
52
55
  d['credit'].each { |h| h['code'] = code_map.dig(h['label']) || CREDIT_DEFAULT }
@@ -67,46 +70,39 @@ module LucaBook
67
70
  end
68
71
  end
69
72
 
70
- def self.validate(obj)
71
- raise 'NoDateKey' unless obj.key?('date')
72
- raise 'NoDebitKey' unless obj.key?('debit')
73
- raise 'NoDebitValue' if obj['debit'].empty?
74
- raise 'NoCreditKey' unless obj.key?('credit')
75
- raise 'NoCreditValue' if obj['credit'].empty?
76
- end
77
-
78
73
  private
79
74
 
80
- #
81
75
  # convert single entry data
82
76
  #
83
77
  def parse_single(row)
84
- value = row.dig(@config[:credit_value])&.empty? ? row[@config[:debit_value]] : row[@config[:credit_value]]
78
+ if (row.dig(@config[:credit_value]) || []).empty?
79
+ value = BigDecimal(row[@config[:debit_value]])
80
+ debit = true
81
+ else
82
+ value = BigDecimal(row[@config[:credit_value]])
83
+ end
84
+ default_label = debit ? @config.dig(:default_debit) : @config.dig(:default_credit)
85
+ code, options = search_code(row[@config[:label]], default_label, value)
86
+ counter_code = @code_map.dig(@config[:counter_label])
87
+ if respond_to? :tax_extension
88
+ data, data_c = tax_extension(code, counter_code, value, options) if options
89
+ end
90
+ data ||= [{ 'code' => code, 'value' => value }]
91
+ data_c ||= [{ 'code' => counter_code, 'value' => value }]
85
92
  {}.tap do |d|
86
93
  d['date'] = parse_date(row)
87
- if row.dig(@config[:credit_value])&.empty?
88
- d['debit'] = [
89
- { 'code' => search_code(row[@config[:label]], @config.dig(:default_debit)) || DEBIT_DEFAULT }
90
- ]
91
- d['credit'] = [
92
- { 'code' => @code_map.dig(@config[:counter_label]) }
93
- ]
94
+ if debit
95
+ d['debit'] = data
96
+ d['credit'] = data_c
94
97
  else
95
- d['debit'] = [
96
- { 'code' => @code_map.dig(@config[:counter_label]) }
97
- ]
98
- d['credit'] = [
99
- { 'code' => search_code(row[@config[:label]], @config.dig(:default_credit)) || CREDIT_DEFAULT }
100
- ]
98
+ d['debit'] = data_c
99
+ d['credit'] = data
101
100
  end
102
- d['debit'][0]['value'] = value
103
- d['credit'][0]['value'] = value
104
101
  d['note'] = Array(@config[:note]).map{ |col| row[col] }.join(' ')
105
102
  d['x-editor'] = "LucaBook::Import/#{@dict_name}"
106
103
  end
107
104
  end
108
105
 
109
- #
110
106
  # convert double entry data
111
107
  #
112
108
  def parse_double(row)
@@ -125,8 +121,9 @@ module LucaBook
125
121
  end
126
122
  end
127
123
 
128
- def search_code(label, default_label)
129
- @code_map.dig(@dict.search(label, default_label))
124
+ def search_code(label, default_label, amount = nil)
125
+ label, options = @dict.search(label, default_label, amount)
126
+ [@code_map.dig(label), options]
130
127
  end
131
128
 
132
129
  def parse_date(row)
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'date'
4
+ require 'luca_book'
5
+ require 'luca_support'
6
+
7
+ module LucaBook
8
+ class Import
9
+ # TODO: need to be separated into pluggable l10n module.
10
+ # TODO: gensen rate >1m yen.
11
+ # TODO: gensen & consumption `round()` rules need to be confirmed.
12
+ # Profit or Loss account should be specified as code1.
13
+ #
14
+ def tax_extension(code1, code2, amount, options)
15
+ return nil if options.nil? || options[:tax_options].nil?
16
+ return nil if !options[:tax_options].include?('jp-gensen') && !options[:tax_options].include?('jp-consumption')
17
+
18
+ gensen_rate = BigDecimal('0.1021')
19
+ consumption_rate = BigDecimal('0.1')
20
+ gensen_code = @code_map.dig(options[:gensen_label]) || @code_map.dig('預り金')
21
+ gensen_idx = /^[5-8B-G]/.match(code1) ? 1 : 0
22
+ consumption_idx = /^[A-G]/.match(code1) ? 0 : 1
23
+ consumption_code = @code_map.dig(options[:consumption_label])
24
+ consumption_code ||= /^[A]/.match(code1) ? @code_map.dig('仮受消費税等') : @code_map.dig('仮払消費税等')
25
+ if options[:tax_options].include?('jp-gensen') && options[:tax_options].include?('jp-consumption')
26
+ paid_rate = BigDecimal('1') + consumption_rate - gensen_rate
27
+ gensen_amount = (amount / paid_rate * gensen_rate).round
28
+ consumption_amount = (amount / paid_rate * consumption_rate).round
29
+ [].tap do |res|
30
+ res << [].tap do |res1|
31
+ amount1 = amount
32
+ amount1 -= consumption_amount if consumption_idx == 0
33
+ amount1 += gensen_amount if gensen_idx == 1
34
+ res1 << { 'code' => code1, 'value' => amount1 }
35
+ res1 << { 'code' => consumption_code, 'value' => consumption_amount } if consumption_idx == 0
36
+ res1 << { 'code' => gensen_code, 'value' => gensen_amount } if gensen_idx == 0
37
+ end
38
+ res << [].tap do |res2|
39
+ amount2 = amount
40
+ amount2 -= consumption_amount if consumption_idx == 1
41
+ amount2 += gensen_amount if gensen_idx == 0
42
+ res2 << { 'code' => code2, 'value' => amount2 }
43
+ res2 << { 'code' => consumption_code, 'value' => consumption_amount } if consumption_idx == 1
44
+ res2 << { 'code' => gensen_code, 'value' => gensen_amount } if gensen_idx == 1
45
+ end
46
+ end
47
+ elsif options[:tax_options].include?('jp-gensen')
48
+ paid_rate = BigDecimal('1') - gensen_rate
49
+ gensen_amount = (amount / paid_rate * gensen_rate).round
50
+ [].tap do |res|
51
+ res << [].tap do |res1|
52
+ amount1 = amount
53
+ amount1 += gensen_amount if gensen_idx == 1
54
+ res1 << { 'code' => code, 'value' => amount1 }
55
+ res1 << { 'code' => gensen_code, 'value' => gensen_amount } if gensen_idx == 0
56
+ end
57
+ res << [].tap do |res2|
58
+ amount2 = amount
59
+ amount2 += gensen_amount if gensen_idx == 0
60
+ mount2 ||= amount
61
+ res2 << { 'code' => code2, 'value' => amount2 }
62
+ res2 << { 'code' => gensen_code, 'value' => gensen_amount } if gensen_idx == 1
63
+ end
64
+ end
65
+ elsif options[:tax_options].include?('jp-consumption')
66
+ paid_rate = BigDecimal('1') + consumption_rate - gensen_rate
67
+ consumption_amount = (amount / paid_rate * consumption_rate).round
68
+ res << [].tap do |res1|
69
+ amount1 = amount
70
+ amount1 -= consumption_amount if consumption_idx == 0
71
+ res1 << { 'code' => code1, 'value' => amount1 }
72
+ res1 << { 'code' => consumption_code, 'value' => consumption_amount } if consumption_idx == 0
73
+ end
74
+ res << [].tap do |res2|
75
+ amount2 = amount
76
+ amount2 -= consumption_amount if consumption_idx == 1
77
+ res2 << { 'code' => code2, 'value' => amount2 }
78
+ res2 << { 'code' => consumption_code, 'value' => consumption_amount } if consumption_idx == 1
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -13,6 +13,7 @@ module LucaBook
13
13
  # create journal from hash
14
14
  #
15
15
  def self.create(d)
16
+ validate(d)
16
17
  date = Date.parse(d['date'])
17
18
 
18
19
  debit_amount = LucaSupport::Code.decimalize(serialize_on_key(d['debit'], 'value'))
@@ -52,6 +53,22 @@ module LucaBook
52
53
  end
53
54
  end
54
55
 
56
+ def self.validate(obj)
57
+ raise 'NoDateKey' unless obj.key?('date')
58
+ raise 'NoDebitKey' unless obj.key?('debit')
59
+ raise 'NoCreditKey' unless obj.key?('credit')
60
+ debit_codes = serialize_on_key(obj['debit'], 'code').compact
61
+ debit_values = serialize_on_key(obj['debit'], 'value').compact
62
+ raise 'NoDebitCode' if debit_codes.empty?
63
+ raise 'NoDebitValue' if debit_values.empty?
64
+ raise 'UnmatchDebit' if debit_codes.length != debit_values.length
65
+ credit_codes = serialize_on_key(obj['credit'], 'code').compact
66
+ credit_values = serialize_on_key(obj['credit'], 'value').compact
67
+ raise 'NoCreditCode' if credit_codes.empty?
68
+ raise 'NoCreditValue' if credit_values.empty?
69
+ raise 'UnmatchCredit' if credit_codes.length != credit_values.length
70
+ end
71
+
55
72
  # collect values on specified key
56
73
  #
57
74
  def self.serialize_on_key(array_of_hash, key)
@@ -47,7 +47,7 @@ module LucaBook
47
47
  res['note'] = dat[:note]
48
48
  end
49
49
  end
50
- self
50
+ readable(@data)
51
51
  end
52
52
 
53
53
  def list_journals
@@ -65,7 +65,7 @@ module LucaBook
65
65
  res['note'] = dat[:note]
66
66
  end
67
67
  end
68
- self
68
+ readable(@data)
69
69
  end
70
70
 
71
71
  def accumulate_code
@@ -74,10 +74,6 @@ module LucaBook
74
74
  end
75
75
  end
76
76
 
77
- def to_yaml
78
- YAML.dump(LucaSupport::Code.readable(@data)).tap { |data| puts data }
79
- end
80
-
81
77
  private
82
78
 
83
79
  def set_balance
@@ -17,28 +17,15 @@ module LucaBook
17
17
 
18
18
  attr_reader :statement
19
19
 
20
- def initialize(data, count = nil)
20
+ def initialize(data, count = nil, date: nil)
21
21
  @data = data
22
22
  @count = count
23
23
  @dict = LucaRecord::Dict.load('base.tsv')
24
+ @start_date = date
24
25
  @start_balance = set_balance
25
26
  end
26
27
 
27
- # TODO: not compatible with LucaRecord::Base.open_records
28
- def search_tag(code)
29
- count = 0
30
- Dir.children(LucaSupport::Config::Pjdir).sort.each do |dir|
31
- next if ! FileTest.directory?(LucaSupport::Config::Pjdir+dir)
32
-
33
- open_records(datadir, dir, 3) do |row, i|
34
- next if i == 2
35
- count += 1 if row.include?(code)
36
- end
37
- end
38
- puts "#{code}: #{count}"
39
- end
40
-
41
- def self.term(from_year, from_month, to_year = from_year, to_month = from_month)
28
+ def self.range(from_year, from_month, to_year = from_year, to_month = from_month)
42
29
  date = Date.new(from_year.to_i, from_month.to_i, -1)
43
30
  last_date = Date.new(to_year.to_i, to_month.to_i, -1)
44
31
  raise 'invalid term specified' if date > last_date
@@ -47,56 +34,57 @@ module LucaBook
47
34
  reports = [].tap do |r|
48
35
  while date <= last_date do
49
36
  diff, count = accumulate_month(date.year, date.month)
50
- r << diff
51
- counts << count
52
- date = date.next_month
37
+ r << diff.tap { |c| c['_d'] = date.to_s }
38
+ counts << count.tap { |c| c['_d'] = date.to_s }
39
+ date = Date.new(date.next_month.year, date.next_month.month, -1)
53
40
  end
54
41
  end
55
- new reports, counts
42
+ new(reports, counts, date: Date.new(from_year.to_i, from_month.to_i, -1))
56
43
  end
57
44
 
58
- def by_code(code, year=nil, month=nil)
59
- raise 'not supported year range yet' if ! year.nil? && month.nil?
60
-
61
- balance = @book.load_start.dig(code) || 0
62
- full_term = self.class.scan_terms
63
- if ! month.nil?
64
- pre_term = full_term.select { |y, m| y <= year.to_i && m < month.to_i }
65
- balance += pre_term.map { |y, m| self.class.net(y, m)}.inject(0){|sum, h| sum + h[code] }
66
- [{ code: code, balance: balance, note: "#{code} #{@dict.dig(code, :label)}" }] + records_with_balance(year, month, code, balance)
67
- else
68
- start = { code: code, balance: balance, note: "#{code} #{@dict.dig(code, :label)}" }
69
- full_term.map { |y, m| y }.uniq.map { |y|
70
- records_with_balance(y, nil, code, balance)
71
- }.flatten.prepend(start)
72
- end
73
- end
45
+ def self.by_code(code, from_year, from_month, to_year = from_year, to_month = from_month)
46
+ date = Date.new(from_year.to_i, from_month.to_i, -1)
47
+ last_date = Date.new(to_year.to_i, to_month.to_i, -1)
48
+ raise 'invalid term specified' if date > last_date
74
49
 
75
- def records_with_balance(year, month, code, balance)
76
- @book.search(year, month, nil, code).each do |h|
77
- balance += Util.calc_diff(Util.amount_by_code(h[:debit], code), code) - Util.calc_diff(Util.amount_by_code(h[:credit], code), code)
78
- h[:balance] = balance
50
+ reports = [].tap do |r|
51
+ while date <= last_date do
52
+ diff = {}.tap do |h|
53
+ g = gross(date.year, date.month, code: code)
54
+ sum = g.dig(:debit).nil? ? BigDecimal('0') : Util.calc_diff(g[:debit], code)
55
+ sum -= g.dig(:credit).nil? ? BigDecimal('0') : Util.calc_diff(g[:credit], code)
56
+ h['code'] = code
57
+ h['label'] = LucaRecord::Dict.load('base.tsv').dig(code, :label)
58
+ h['net'] = sum
59
+ h['debit_amount'] = g[:debit]
60
+ h['debit_count'] = g[:debit_count]
61
+ h['credit_amount'] = g[:credit]
62
+ h['credit_count'] = g[:credit_count]
63
+ h['_d'] = date.to_s
64
+ end
65
+ r << diff
66
+ date = Date.new(date.next_month.year, date.next_month.month, -1)
67
+ end
79
68
  end
80
- end
81
-
82
- def to_yaml
83
- YAML.dump(code2label).tap { |data| puts data }
69
+ LucaSupport::Code.readable(reports)
84
70
  end
85
71
 
86
72
  def code2label
87
73
  @statement ||= @data
88
74
  @statement.map do |report|
89
75
  {}.tap do |h|
90
- report.each { |k, v| h[@dict.dig(k, :label)] = v }
76
+ report.each { |k, v| h[@dict.dig(k, :label) || k] = v }
91
77
  end
92
78
  end
93
79
  end
94
80
 
95
81
  def stats(level = nil)
96
- keys = @count.map(&:keys).flatten.uniq.sort
82
+ keys = @count.map(&:keys).flatten.push('_t').uniq.sort
97
83
  @count.map! do |data|
84
+ sum = 0
98
85
  keys.each do |k|
99
86
  data[k] ||= 0
87
+ sum += data[k] if /^[^_]/.match(k)
100
88
  next if level.nil? || k.length <= level
101
89
 
102
90
  if data[k[0, level]]
@@ -106,34 +94,34 @@ module LucaBook
106
94
  end
107
95
  end
108
96
  data.select! { |k, _v| k.length <= level } if level
97
+ data['_t'] = sum
109
98
  data.sort.to_h
110
99
  end
111
100
  keys.map! { |k| k[0, level] }.uniq.select! { |k| k.length <= level } if level
112
101
  @count.prepend({}.tap { |header| keys.each { |k| header[k] = @dict.dig(k, :label) }})
113
- puts YAML.dump(@count)
114
102
  @count
115
103
  end
116
104
 
117
105
  def bs(level = 3, legal: false)
106
+ @start_balance.keys.each { |k| @data.first[k] ||= 0 }
118
107
  @data.map! { |data| data.select { |k, _v| k.length <= level } }
119
108
  @data.map! { |data| code_sum(data).merge(data) } if legal
120
109
  base = accumulate_balance(@data)
121
- length = [base[:debit].length, base[:credit].length].max
110
+ rows = [base[:debit].length, base[:credit].length].max
122
111
  @statement = [].tap do |a|
123
- length.times do |i|
112
+ rows.times do |i|
124
113
  {}.tap do |res|
125
114
  res['debit_label'] = base[:debit][i] ? @dict.dig(base[:debit][i].keys[0], :label) : ''
126
- res['debit_balance'] = base[:debit][i] ? @start_balance.dig(base[:debit][i].keys[0]) + base[:debit][i].values[0] : ''
115
+ res['debit_balance'] = base[:debit][i] ? (@start_balance.dig(base[:debit][i].keys[0]) || 0) + base[:debit][i].values[0] : ''
127
116
  res['debit_diff'] = base[:debit][i] ? base[:debit][i].values[0] : ''
128
117
  res['credit_label'] = base[:credit][i] ? @dict.dig(base[:credit][i].keys[0], :label) : ''
129
- res['credit_balance'] = base[:credit][i] ? @start_balance.dig(base[:credit][i].keys[0]) + base[:credit][i].values[0] : ''
118
+ res['credit_balance'] = base[:credit][i] ? (@start_balance.dig(base[:credit][i].keys[0]) || 0) + base[:credit][i].values[0] : ''
130
119
  res['credit_diff'] = base[:credit][i] ? base[:credit][i].values[0] : ''
131
120
  a << res
132
121
  end
133
122
  end
134
123
  end
135
- puts YAML.dump(@statement)
136
- self
124
+ readable(@statement)
137
125
  end
138
126
 
139
127
  def accumulate_balance(monthly_diffs)
@@ -141,23 +129,58 @@ module LucaBook
141
129
  month.each do |k, v|
142
130
  h[k] = h[k].nil? ? v : h[k] + v
143
131
  end
144
- end.sort.to_h
132
+ end
145
133
  { debit: [], credit: [] }.tap do |res|
146
- data.each do |k, v|
134
+ data.sort.to_h.each do |k, v|
147
135
  case k
148
136
  when /^[0-4].*/
149
137
  res[:debit] << { k => v }
150
- when /^[5-9H].*/
138
+ when /^[5-9].*/
151
139
  res[:credit] << { k => v }
152
140
  end
153
141
  end
154
142
  end
155
143
  end
156
144
 
157
- def pl
158
- @statement = @data.map { |data| data.select { |k, _v| /^[A-H].+/.match(k) } }
159
- @statement << @statement.each_with_object({}) { |item, h| item.each { |k, v| h[k].nil? ? h[k] = v : h[k] += v } }
160
- self
145
+ def pl(level = 2)
146
+ term_keys = @data.inject([]) { |a, data| a + data.keys }
147
+ .compact.select { |k| /^[A-H_].+/.match(k) }
148
+ fy = @start_balance.select { |k, _v| /^[A-H].+/.match(k) }
149
+ keys = (term_keys + fy.keys).uniq.sort
150
+ keys.select! { |k| k.length <= level }
151
+ @statement = @data.map do |data|
152
+ {}.tap do |h|
153
+ keys.each { |k| h[k] = data[k] || BigDecimal('0') }
154
+ end
155
+ end
156
+ term = @statement.each_with_object({}) do |item, h|
157
+ item.each do |k, v|
158
+ h[k] = h[k].nil? ? v : h[k] + v if /^[^_]/.match(k)
159
+ end
160
+ end
161
+ fy = {}.tap do |h|
162
+ keys.each do |k|
163
+ h[k] = BigDecimal(fy[k] || '0') + BigDecimal(term[k] || '0')
164
+ end
165
+ end
166
+ @statement << term.tap { |h| h['_d'] = 'Period Total' }
167
+ @statement << fy.tap { |h| h['_d'] = 'FY Total' }
168
+ readable(code2label)
169
+ end
170
+
171
+ def self.accumulate_term(start_year, start_month, end_year, end_month)
172
+ date = Date.new(start_year, start_month, 1)
173
+ last_date = Date.new(end_year, end_month, -1)
174
+ return nil if date > last_date
175
+
176
+ {}.tap do |res|
177
+ diff, _count = net(date.year, date.month, last_date.year, last_date.month)
178
+ diff.each do |k, v|
179
+ next if /^[_]/.match(k)
180
+
181
+ res[k] = res[k].nil? ? v : res[k] + v
182
+ end
183
+ end
161
184
  end
162
185
 
163
186
  def self.accumulate_month(year, month)
@@ -169,12 +192,6 @@ module LucaBook
169
192
  #
170
193
  def self.total_subaccount(report)
171
194
  {}.tap do |res|
172
- res['10'] = sum_matched(report, /^[123][0-9A-Z]{2,}/)
173
- res['40'] = sum_matched(report, /^[4][0-9A-Z]{2,}/)
174
- res['50'] = sum_matched(report, /^[56][0-9A-Z]{2,}/)
175
- res['70'] = sum_matched(report, /^[78][0-9A-Z]{2,}/)
176
- res['8ZZ'] = res['50'] + res['70']
177
- res['9ZZ'] = sum_matched(report, /^[9][0-9A-Z]{2,}/)
178
195
  res['A0'] = sum_matched(report, /^[A][0-9A-Z]{2,}/)
179
196
  res['B0'] = sum_matched(report, /^[B][0-9A-Z]{2,}/)
180
197
  res['BA'] = res['A0'] - res['B0']
@@ -184,12 +201,28 @@ module LucaBook
184
201
  res['E0'] = sum_matched(report, /^[E][0-9A-Z]{2,}/)
185
202
  res['EA'] = res['CA'] + res['D0'] - res['E0']
186
203
  res['F0'] = sum_matched(report, /^[F][0-9A-Z]{2,}/)
187
- res['G0'] = sum_matched(report, /^[G][0-9A-Z]{2,}/)
204
+ res['G0'] = sum_matched(report, /^[G][0-9][0-9A-Z]{1,}/)
188
205
  res['GA'] = res['EA'] + res['F0'] - res['G0']
189
- res['HA'] = res['GA'] - sum_matched(report, /^[H][0-9A-Z]{2,}/)
206
+ res['H0'] = sum_matched(report, /^[H][0-9][0-9A-Z]{1,}/)
207
+ res['HA'] = res['GA'] - res['H0']
208
+
209
+ report['9142'] = (report['9142'] || BigDecimal('0')) + res['HA']
210
+ res['9142'] = report['9142']
211
+ res['10'] = sum_matched(report, /^[123][0-9A-Z]{2,}/)
212
+ res['40'] = sum_matched(report, /^[4][0-9A-Z]{2,}/)
213
+ res['50'] = sum_matched(report, /^[56][0-9A-Z]{2,}/)
214
+ res['70'] = sum_matched(report, /^[78][0-9A-Z]{2,}/)
215
+ res['91'] = sum_matched(report, /^91[0-9A-Z]{1,}/)
216
+ res['8ZZ'] = res['50'] + res['70']
217
+ res['9ZZ'] = sum_matched(report, /^[9][0-9A-Z]{2,}/)
190
218
 
191
219
  res['1'] = res['10'] + res['40']
192
- res['5'] = res['8ZZ'] + res['9ZZ'] + res['HA']
220
+ res['5'] = res['8ZZ'] + res['9ZZ']
221
+ res['_d'] = report['_d']
222
+
223
+ report.each do |k, v|
224
+ res[k] = v if k.length == 3
225
+ end
193
226
 
194
227
  report.each do |k, v|
195
228
  if k.length >= 4
@@ -211,10 +244,23 @@ module LucaBook
211
244
  end
212
245
 
213
246
  def set_balance
247
+ pre_last = @start_date.prev_month
248
+ pre = if @start_date.month > LucaSupport::CONFIG['fy_start'].to_i
249
+ self.class.accumulate_term(pre_last.year, LucaSupport::CONFIG['fy_start'], pre_last.year, pre_last.month)
250
+ elsif @start_date.month < LucaSupport::CONFIG['fy_start'].to_i
251
+ self.class.accumulate_term(pre_last.year - 1, LucaSupport::CONFIG['fy_start'], pre_last.year, pre_last.month)
252
+ end
253
+
214
254
  base = Dict.latest_balance.each_with_object({}) do |(k, v), h|
215
- h[k] = v[:balance].to_i if v[:balance]
255
+ h[k] = BigDecimal(v[:balance].to_s) if v[:balance]
256
+ end
257
+ if pre
258
+ idx = (pre.keys + base.keys).uniq
259
+ base = {}.tap do |h|
260
+ idx.each { |k| h[k] = (base[k] || BigDecimal('0')) + (pre[k] || BigDecimal('0')) }
261
+ end
216
262
  end
217
- code_sum(base).merge(self.class.total_subaccount(base))
263
+ self.class.total_subaccount(base)
218
264
  end
219
265
 
220
266
  def self.sum_matched(report, reg)
@@ -222,39 +268,49 @@ module LucaBook
222
268
  end
223
269
 
224
270
  # for assert purpose
225
- def self.gross(year, month = nil, code = nil, date_range = nil, rows = 4)
271
+ #
272
+ def self.gross(start_year, start_month, end_year = nil, end_month = nil, code: nil, date_range: nil, rows: 4)
226
273
  if ! date_range.nil?
227
274
  raise if date_range.class != Range
228
275
  # TODO: date based range search
229
276
  end
230
277
 
278
+ end_year ||= start_year
279
+ end_month ||= start_month
231
280
  sum = { debit: {}, credit: {}, debit_count: {}, credit_count: {} }
232
281
  idx_memo = []
233
- asof(year, month) do |f, _path|
282
+ term(start_year, start_month, end_year, end_month, code) do |f, _path|
234
283
  CSV.new(f, headers: false, col_sep: "\t", encoding: 'UTF-8')
235
284
  .each_with_index do |row, i|
236
285
  break if i >= rows
286
+
237
287
  case i
238
288
  when 0
239
289
  idx_memo = row.map(&:to_s)
290
+ next if code && !idx_memo.include?(code)
291
+
240
292
  idx_memo.each do |r|
241
- sum[:debit][r] ||= 0
293
+ sum[:debit][r] ||= BigDecimal('0')
242
294
  sum[:debit_count][r] ||= 0
243
295
  end
244
296
  when 1
297
+ next if code && !idx_memo.include?(code)
298
+
245
299
  row.each_with_index do |r, j|
246
- sum[:debit][idx_memo[j]] += r.to_i # TODO: bigdecimal support
300
+ sum[:debit][idx_memo[j]] += BigDecimal(r.to_s)
247
301
  sum[:debit_count][idx_memo[j]] += 1
248
302
  end
249
303
  when 2
250
304
  idx_memo = row.map(&:to_s)
305
+ break if code && !idx_memo.include?(code)
306
+
251
307
  idx_memo.each do |r|
252
- sum[:credit][r] ||= 0
308
+ sum[:credit][r] ||= BigDecimal('0')
253
309
  sum[:credit_count][r] ||= 0
254
310
  end
255
311
  when 3
256
312
  row.each_with_index do |r, j|
257
- sum[:credit][idx_memo[j]] += r.to_i # TODO: bigdecimal support
313
+ sum[:credit][idx_memo[j]] += BigDecimal(r.to_s)
258
314
  sum[:credit_count][idx_memo[j]] += 1
259
315
  end
260
316
  else
@@ -262,41 +318,31 @@ module LucaBook
262
318
  end
263
319
  end
264
320
  end
321
+ if code
322
+ sum[:debit] = sum[:debit][code] || BigDecimal('0')
323
+ sum[:credit] = sum[:credit][code] || BigDecimal('0')
324
+ sum[:debit_count] = sum[:debit_count][code] || 0
325
+ sum[:credit_count] = sum[:credit_count][code] || 0
326
+ end
265
327
  sum
266
328
  end
267
329
 
268
330
  # netting vouchers in specified term
269
- def self.net(year, month = nil, code = nil, date_range = nil)
270
- g = gross(year, month, code, date_range)
331
+ #
332
+ def self.net(start_year, start_month, end_year = nil, end_month = nil, code: nil, date_range: nil)
333
+ g = gross(start_year, start_month, end_year, end_month, code: code, date_range: date_range)
271
334
  idx = (g[:debit].keys + g[:credit].keys).uniq.sort
272
335
  count = {}
273
336
  diff = {}.tap do |sum|
274
337
  idx.each do |code|
275
- sum[code] = g.dig(:debit, code).nil? ? 0 : Util.calc_diff(g[:debit][code], code)
276
- sum[code] -= g.dig(:credit, code).nil? ? 0 : Util.calc_diff(g[:credit][code], code)
338
+ sum[code] = g.dig(:debit, code).nil? ? BigDecimal('0') : Util.calc_diff(g[:debit][code], code)
339
+ sum[code] -= g.dig(:credit, code).nil? ? BigDecimal('0') : Util.calc_diff(g[:credit][code], code)
277
340
  count[code] = (g.dig(:debit_count, code) || 0) + (g.dig(:credit_count, code) || 0)
278
341
  end
279
342
  end
280
343
  [diff, count]
281
344
  end
282
345
 
283
- # TODO: replace load_tsv -> generic load_tsv_dict
284
- def load_start
285
- file = Pathname(LucaSupport::Config::Pjdir) / 'data' / 'balance' / 'start.tsv'
286
- {}.tap do |dic|
287
- load_tsv(file) do |row|
288
- dic[row[0]] = row[2].to_i if ! row[2].nil?
289
- end
290
- end
291
- end
292
-
293
- def load_tsv(path)
294
- return enum_for(:load_tsv, path) unless block_given?
295
-
296
- data = CSV.read(path, headers: true, col_sep: "\t", encoding: 'UTF-8')
297
- data.each { |row| yield row }
298
- end
299
-
300
346
  private
301
347
 
302
348
  def legal_items
@@ -1,19 +1,19 @@
1
- code label xbrl_id consumption_tax income_tax
1
+ code label xbrl_id consumption_tax income_tax
2
2
  10 Current Assets
3
3
  10XX UNSETTLED_IMPORT
4
4
  110 Cash and cash equivalents
5
5
  1101 Saving accounts
6
6
  1102 Checking accounts
7
- 111 Cash,us-gaap:Cash
8
- 120 Notes receivable,us-gaap:NotesReceivableGross
9
- 130 Accounts receivable - trade,us-gaap:AccountsReceivableGross
7
+ 111 Cash us-gaap:Cash
8
+ 120 Notes receivable us-gaap:NotesReceivableGross
9
+ 130 Accounts receivable - trade us-gaap:AccountsReceivableGross
10
10
  140 短期貸付金
11
11
  150 未収入金
12
- 160 Inventory,us-gaap:InventoryGross
12
+ 160 Inventory us-gaap:InventoryGross
13
13
  161 商品
14
14
  162 製品
15
- 163 Inventory work in process,us-gaap:InventoryWorkInProcess
16
- 164 Supplies,us-gaap:Supplies
15
+ 163 Inventory work in process us-gaap:InventoryWorkInProcess
16
+ 164 Supplies us-gaap:Supplies
17
17
  180 その他流動資産
18
18
  181 前渡金
19
19
  182 Prepaid expenses
@@ -22,17 +22,17 @@ code label xbrl_id consumption_tax income_tax
22
22
  1D0 Deferred income tax
23
23
  40 Fixed Assets
24
24
  410 Tangible Assets
25
- 411 Buildings,us-gaap:BuildingsAndImprovementsGross
25
+ 411 Buildings us-gaap:BuildingsAndImprovementsGross
26
26
  412 Equipment
27
27
  413 Machinery
28
28
  414 Vehicles
29
29
  415 Tools
30
30
  416 Land
31
- 417 Construction in progress,us-gaap:ConstructionInProgressGross
31
+ 417 Construction in progress us-gaap:ConstructionInProgressGross
32
32
  418 Ships
33
33
  420 Intangible Assets
34
34
  421 Software
35
- 422 Goodwill,us-gaap:Goodwill
35
+ 422 Goodwill us-gaap:Goodwill
36
36
  423 Patents
37
37
  424 借地権
38
38
  425 商標権
@@ -52,10 +52,10 @@ code label xbrl_id consumption_tax income_tax
52
52
  443 社債発行費
53
53
  50 Current Liabilities
54
54
  50XX UNSETTLED_IMPORT
55
- 510 Notes payable,us-gaap:NotesPayable
55
+ 510 Notes payable us-gaap:NotesPayable
56
56
  511 Accounts payable - trade
57
- 512 Short-term borrowings,us-gaap:ShortermBorrowings
58
- 513 Commercial paper,us-gaap:CommercialPaper
57
+ 512 Short-term borrowings us-gaap:ShortermBorrowings
58
+ 513 Commercial paper us-gaap:CommercialPaper
59
59
  514 Accounts payable - other
60
60
  515 Income taxes payable
61
61
  516 未払消費税等
@@ -66,7 +66,7 @@ code label xbrl_id consumption_tax income_tax
66
66
  51B Deferred tax liabilities
67
67
  70 Long-term Liabilities
68
68
  711 Debt securities
69
- 712 Loans payable,us-gaap:LoansPayable
69
+ 712 Loans payable us-gaap:LoansPayable
70
70
  713 退職給付引当金
71
71
  714 Deferred tax liabilities
72
72
  90 Net Assets
@@ -74,7 +74,7 @@ code label xbrl_id consumption_tax income_tax
74
74
  911 Capital stock
75
75
  912 Capital surplus
76
76
  913 Retained earnings
77
- 914 Treasury stock,us-gaap:TreasuryStockValue
77
+ 914 Treasury stock us-gaap:TreasuryStockValue
78
78
  920 評価換算差額等
79
79
  921 有価証券評価差額金
80
80
  922 為替換算調整勘定
@@ -88,33 +88,38 @@ B12 Parts
88
88
  B13 Labor
89
89
  BA Gross profit
90
90
  C0 Operating expenses
91
- C11 Officers Compensation,us-gaap:OfficersCompensation
92
- C12 Salaries,us-gaap:SalariesAndWages
91
+ C11 Officers Compensation us-gaap:OfficersCompensation
92
+ C12 Salaries us-gaap:SalariesAndWages
93
93
  C13 Bonuses
94
94
  C14 役員賞与
95
95
  C15 退職金
96
96
  C16 Legal welfare
97
- C17 Travel,us-gaap:TravelAndEntertainmentExpense
98
- C18 Communication,us-gaap:Communication
99
- C19 Repairs,us-gaap:CostOfPropertyRepairsAndMaintenance
100
- C1A Advertising,us-gaap:AdvertisingExpense
97
+ C17 Travel us-gaap:TravelAndEntertainmentExpense
98
+ C18 Communication us-gaap:Communication
99
+ C19 Repairs us-gaap:CostOfPropertyRepairsAndMaintenance
100
+ C1A Advertising us-gaap:AdvertisingExpense
101
101
  C1B Entertainment
102
102
  C1C Packing-and-freight
103
103
  C1D Welfare
104
104
  C1E Rents
105
105
  C1F Utilities
106
- C1G Supplies,us-gaap:SuppliesExpense
106
+ C1G Supplies us-gaap:SuppliesExpense
107
107
  C1H Insurance
108
108
  C1I Taxes
109
109
  C1J 賃借料
110
110
  C1K Books
111
111
  C1L 貸倒損失
112
112
  C1M 諸会費
113
- C1N Fees and commisions,us-gaap:BankingFeesAndCommisions
113
+ C1N Fees and commisions us-gaap:BankingFeesAndCommisions
114
114
  C1O 外注費
115
115
  C1P Depreciation
116
116
  C1Q Miscellaneous
117
117
  C1R 貸倒引当金繰入
118
+ C1S 支払報酬
119
+ C1T 研修費
120
+ C1U 採用費
121
+ C1V 業務委託費
122
+ C1W 会議費
118
123
  CA Operating profit/loss
119
124
  D0 営業外収益
120
125
  D11 Interest income
@@ -139,4 +144,6 @@ G11 固定資産売却損
139
144
  G12 固定資産除却損
140
145
  G13 災害損失
141
146
  GA Income before taxes
147
+ H0 Income Taxes
148
+ H11 Income Taxes Current
142
149
  HA Net Income/Loss
@@ -1,5 +1,5 @@
1
1
  code label xbrl_id consumption_tax income_tax
2
- 1 資産合計
2
+ 1 資産合計 jppfs_cor:AssetsAbstract
3
3
  10 流動資産 jppfs_cor:CurrentAssetsAbstract
4
4
  10XX UNSETTLED_IMPORT
5
5
  110 現金及び預金 jppfs_cor:CashAndDeposits
@@ -55,7 +55,7 @@ code label xbrl_id consumption_tax income_tax
55
55
  442 創立費 jppfs_cor:DeferredOrganisationExpensesDA
56
56
  442 新株発行費 jppfs_cor:StockIssuanceCostDA
57
57
  443 社債発行費 jppfs_cor:BondIssuanceCostDA
58
- 5 負債・純資産合計
58
+ 5 負債・純資産合計 jppfs_cor:LiabilitiesAndNetAssets
59
59
  50 流動負債 jppfs_cor:CurrentLiabilitiesAbstract
60
60
  50XX UNSETTLED_IMPORT
61
61
  510 支払手形 jppfs_cor:NotePayableTrade
@@ -74,25 +74,24 @@ code label xbrl_id consumption_tax income_tax
74
74
  712 長期借入金 jppfs_cor:LongTermLoansPayable
75
75
  713 退職給付引当金 jppfs_cor:ProvisionForRetirementBenefits
76
76
  714 繰延税金負債 jppfs_cor:DeferredTaxLiabilities
77
- 8ZZ 負債合計
78
- 90 純資産 jppfs_cor:NetAssetsAbstract
77
+ 8ZZ 負債合計 jppfs_cor:LiabilitiesAbstract
79
78
  91 株主資本 jppfs_cor:ShareholdersAbstract
80
79
  911 資本金 jppfs_cor:CapitalStock
81
- 912 新株式申込証拠金
80
+ 912 新株式申込証拠金 jppfs_cor:DepositForSubscriptionsToShares
82
81
  913 資本剰余金 jppfs_cor:LegalCapitalSurplus
83
- 9131 資本準備金
84
- 9132 その他資本剰余金
82
+ 9131 資本準備金 jppfs_cor:LegalCapitalSurplus
83
+ 9132 その他資本剰余金 jppfs_cor:OtherCapitalSurplus
85
84
  914 利益剰余金 jppfs_cor:RetainedEarnings
86
- 9141 利益準備金
87
- 9142 その他利益剰余金
85
+ 9141 利益準備金 jppfs_cor:LegalRetainedEarnings
86
+ 9142 その他利益剰余金 jppfs_cor:OtherRetainedEarningsAbstract
88
87
  915 自己株式 jppfs_cor:TreasuryStock
89
- 916 自己株式申込証拠金
88
+ 916 自己株式申込証拠金 jppfs_cor:DepositForSubscriptionsToTreasuryStock
90
89
  92 評価換算差額等 jppfs_cor:ValuationAndTranslationAdjustments
91
90
  921 有価証券評価差額金 jppfs_cor:ValuationDifferenceOnAvailableForSaleSecurities
92
91
  922 為替換算調整勘定 jppfs_cor:ForeignCurrencyTranslationAdjustment
93
92
  93 新株予約権 jppfs_cor:SubscriptionRightsToShares
94
93
  940 非支配株主持分 jppfs_cor:NonControllingInterests
95
- 9ZZ 純資産合計
94
+ 9ZZ 純資産合計 jppfs_cor:NetAssetsAbstract
96
95
  A0 売上 jppfs_cor:NetSalesAbstract
97
96
  A11 売上高 jppfs_cor:NetSales
98
97
  B0 売上原価 jppfs_cor:CostOfSalesAbstract
@@ -130,7 +129,11 @@ C1O 外注費 jppfs_cor:SubcontructExpensesSGA
130
129
  C1P 減価償却費 jppfs_cor:DepreciationSGA
131
130
  C1Q 雑費 jppfs_cor:MiscellaneousExpensesSGA
132
131
  C1R 貸倒引当金繰入 jppfs_cor:ProvisionOfAllowanceForDebtfulAccountsSGA
133
- C1S 支払報酬
132
+ C1S 支払報酬 jppfs_cor:CompensationsSGA
133
+ C1T 研修費 jppfs_cor:TrainingExpensesSGA
134
+ C1U 採用費 jppfs_cor:RecruitingExpensesSGA
135
+ C1V 業務委託費 jppfs_cor:BusinessConsignmentExpensesSGA
136
+ C1W 会議費 jppfs_cor:ConferenceExpensesSGA
134
137
  CA 営業利益 jppfs_cor:OperatingIncome
135
138
  D0 営業外収益 jppfs_cor:NonOperatingIncomeAbstract
136
139
  D11 受取利息 jppfs_cor:InterestIncomeNOI
@@ -154,5 +157,7 @@ G0 特別損失 jppfs_cor:ExtraordinaryLossAbstract
154
157
  G11 固定資産売却損 jppfs_cor:LossOnSalesOfNoncurrentAssetsEL
155
158
  G12 固定資産除却損 jppfs_cor:LossOnRetirementOfNoncurrentAssetsEL
156
159
  G13 災害損失 jppfs_cor:LossOnDisasterEL
157
- GA 税引前純利益 jppfs_cor:IncomeBeforeIncomeTaxes
160
+ GA 税引前利益 jppfs_cor:IncomeBeforeIncomeTaxes
161
+ H0 法人税等 jppfs_cor:IncomeTaxes
162
+ H11 法人税、住民税及び事業税 jppfs_cor:IncomeTaxesCurrent
158
163
  HA 当期利益 jppfs_cor:ProfitLoss
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LucaBook
4
- VERSION = '0.2.17'
4
+ VERSION = '0.2.22'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lucabook
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.17
4
+ version: 0.2.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chuma Takahiro
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-11-18 00:00:00.000000000 Z
11
+ date: 2020-11-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lucarecord
@@ -82,9 +82,9 @@ files:
82
82
  - lib/luca_book/console.rb
83
83
  - lib/luca_book/dict.rb
84
84
  - lib/luca_book/import.rb
85
+ - lib/luca_book/import_jp.rb
85
86
  - lib/luca_book/journal.rb
86
87
  - lib/luca_book/list.rb
87
- - lib/luca_book/report.rb
88
88
  - lib/luca_book/setup.rb
89
89
  - lib/luca_book/state.rb
90
90
  - lib/luca_book/templates/base-jp.xbrl.erb
@@ -1,3 +0,0 @@
1
- # move to LucaBook::State
2
- class LucaBookReport
3
- end