lucabook 0.2.17 → 0.2.22

Sign up to get free protection for your applications and to get access to all the features.
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