lucabook 0.2.26 → 0.2.27

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: 933e3d04315c04b7f6e998b16499b458ceeeafe8bfae9ce4ef4422018eb17040
4
- data.tar.gz: 2e243b4e85cdc50bd45e39ed311cf78a8aa12e1956be0d0273c2a634147be16c
3
+ metadata.gz: ad4b1eba3419508d64bfeade5f776ed2ca0f32313deab25660864aff47767787
4
+ data.tar.gz: 57aef956cbc763dbf4d089d5745c9cc4d6a6ed44dd3ff726b9c80fbc6b29629d
5
5
  SHA512:
6
- metadata.gz: b2292a4972ce1fcf883a828d17479f1580e3145e0db2d26ff6044a73495d2e151d60f0bd98fd5b2f945c3b74cdff879f9f7779073487c05c70a078306b069bbe
7
- data.tar.gz: 27bf6b4bcea1b2eb9d5dac761d5465ce478af02a4074f0a20038b7f8a21c528b66faf399d4364702ebf22f06cc0a0112d13a4ee2e10acb22eb16b52859aaf4b6
6
+ metadata.gz: 317b373f1a31c85c107dfa294ec6df0dcc89f13b8ab10277bb004b3bdceaaf0ec58cfa5c2220a088932965b5b156fd71fef1ce67be67c330857bbcea127de365
7
+ data.tar.gz: e7456d393a4309bafb9a3622c28da10067e1483c80b0bbbd73a05508bb3d9a6742051e2d190870a1f6e39df5ec10b5dd7d1de698faef969a3bc54efa7b46b153
data/exe/luca-book CHANGED
@@ -24,7 +24,7 @@ class LucaCmd
24
24
  if params['headers']
25
25
  render(LucaBook::ListByHeader.term(*args, code: params['code'], header: params['headers']).list_by_code, params)
26
26
  else
27
- render(LucaBook::List.term(*args, code: params['code']).list_by_code, params)
27
+ render(LucaBook::List.term(*args, code: params['code'], recursive: params[:recursive]).list_by_code(params[:recursive]), params)
28
28
  end
29
29
  else
30
30
  render(LucaBook::List.term(*args).list_journals, params)
@@ -34,7 +34,7 @@ class LucaCmd
34
34
  def self.stats(args, params)
35
35
  args = gen_range(params[:n]) if args.empty?
36
36
  if params['code']
37
- render(LucaBook::State.by_code(params['code'], *args), params)
37
+ render(LucaBook::State.by_code(params['code'], *args, recursive: params[:recursive]), params)
38
38
  else
39
39
  render(LucaBook::State.range(*args).stats(params[:level]), params)
40
40
  end
@@ -124,9 +124,11 @@ when /journals?/, 'j'
124
124
  LucaCmd::Journal.import(args, params)
125
125
  end
126
126
  when 'list'
127
+ params[:recursive] = false
127
128
  OptionParser.new do |opt|
128
129
  opt.banner = 'Usage: luca-book journals list [options] [YYYY M]'
129
130
  opt.on('-c', '--code VAL', 'filter with code or label') { |v| params['code'] = v }
131
+ opt.on('-r', '--recursive', 'include subaccounts') { |_v| params[:recursive] = true }
130
132
  opt.on('--customer', 'categorize by x-customer header') { |_v| params['headers'] = 'x-customer' }
131
133
  opt.on('-n VAL', 'report count') { |v| params[:n] = v.to_i }
132
134
  opt.on('--nu', 'show table in nushell') { |_v| params[:output] = 'nu' }
@@ -146,9 +148,11 @@ when /journals?/, 'j'
146
148
  LucaCmd::Journal.add_header(args, params)
147
149
  end
148
150
  when 'stats'
151
+ params[:recursive] = false
149
152
  OptionParser.new do |opt|
150
153
  opt.banner = 'Usage: luca-book journals stats [options] [YYYY M]'
151
154
  opt.on('-c', '--code VAL', 'filter with code or label') { |v| params['code'] = v }
155
+ opt.on('-r', '--recursive', 'include subaccounts') { |_v| params[:recursive] = true }
152
156
  opt.on('-n VAL', 'report count') { |v| params[:n] = v.to_i }
153
157
  opt.on('--nu', 'show table in nushell') { |_v| params[:output] = 'nu' }
154
158
  opt.on('-o', '--output VAL', 'output serialized data') { |v| params[:output] = v }
@@ -74,7 +74,7 @@ module LucaBook
74
74
 
75
75
  # for assert purpose
76
76
  #
77
- def gross(start_year, start_month, end_year = nil, end_month = nil, code: nil, date_range: nil, rows: 4)
77
+ def gross(start_year, start_month, end_year = nil, end_month = nil, code: nil, date_range: nil, rows: 4, recursive: false)
78
78
  if ! date_range.nil?
79
79
  raise if date_range.class != Range
80
80
  # TODO: date based range search
@@ -92,14 +92,14 @@ module LucaBook
92
92
  case i
93
93
  when 0
94
94
  idx_memo = row.map(&:to_s)
95
- next if code && !idx_memo.include?(code)
95
+ next if code && idx_memo.select { |idx| /^#{code}/.match(idx) }.empty?
96
96
 
97
97
  idx_memo.each do |r|
98
98
  sum[:debit][r] ||= BigDecimal('0')
99
99
  sum[:debit_count][r] ||= 0
100
100
  end
101
101
  when 1
102
- next if code && !idx_memo.include?(code)
102
+ next if code && idx_memo.select { |idx| /^#{code}/.match(idx) }.empty?
103
103
 
104
104
  row.each_with_index do |r, j|
105
105
  sum[:debit][idx_memo[j]] += BigDecimal(r.to_s)
@@ -107,7 +107,7 @@ module LucaBook
107
107
  end
108
108
  when 2
109
109
  idx_memo = row.map(&:to_s)
110
- break if code && !idx_memo.include?(code)
110
+ break if code && idx_memo.select { |idx| /^#{code}/.match(idx) }.empty?
111
111
 
112
112
  idx_memo.each do |r|
113
113
  sum[:credit][r] ||= BigDecimal('0')
@@ -123,13 +123,21 @@ module LucaBook
123
123
  end
124
124
  end
125
125
  end
126
- if code
127
- sum[:debit] = sum[:debit][code] || BigDecimal('0')
128
- sum[:credit] = sum[:credit][code] || BigDecimal('0')
129
- sum[:debit_count] = sum[:debit_count][code] || 0
130
- sum[:credit_count] = sum[:credit_count][code] || 0
126
+ return sum if code.nil?
127
+
128
+ codes = if recursive
129
+ sum[:debit].keys.concat(sum[:credit].keys).uniq.select { |k| /^#{code}/.match(k) }
130
+ else
131
+ Array(code)
132
+ end
133
+ res = { debit: 0, credit: 0, debit_count: 0, credit_count: 0 }
134
+ codes.each do |code|
135
+ res[:debit] += sum[:debit][code] || BigDecimal('0')
136
+ res[:credit] += sum[:credit][code] || BigDecimal('0')
137
+ res[:debit_count] += sum[:debit_count][code] || 0
138
+ res[:credit_count] += sum[:credit_count][code] || 0
131
139
  end
132
- sum
140
+ res
133
141
  end
134
142
 
135
143
  # netting vouchers in specified term
@@ -21,13 +21,17 @@ module LucaBook #:nodoc:
21
21
  @start = start_date
22
22
  end
23
23
 
24
- def self.term(from_year, from_month, to_year = from_year, to_month = from_month, code: nil, basedir: @dirname)
24
+ def self.term(from_year, from_month, to_year = from_year, to_month = from_month, code: nil, basedir: @dirname, recursive: false)
25
25
  code = search_code(code) if code
26
26
  data = LucaBook::Journal.term(from_year, from_month, to_year, to_month, code).select do |dat|
27
27
  if code.nil?
28
28
  true
29
29
  else
30
- [:debit, :credit].map { |key| serialize_on_key(dat[key], :code) }.flatten.include?(code)
30
+ if recursive
31
+ ! [:debit, :credit].map { |key| serialize_on_key(dat[key], :code) }.flatten.select { |idx| /^#{code}/.match(idx) }.empty?
32
+ else
33
+ [:debit, :credit].map { |key| serialize_on_key(dat[key], :code) }.flatten.include?(code)
34
+ end
31
35
  end
32
36
  end
33
37
  new data, Date.new(from_year.to_i, from_month.to_i, 1), code
@@ -43,13 +47,13 @@ module LucaBook #:nodoc:
43
47
  end
44
48
  end
45
49
 
46
- def list_by_code
47
- calc_code
50
+ def list_by_code(recursive = false)
51
+ calc_code(recursive: recursive)
48
52
  convert_label
49
53
  @data = [code_header] + @data.map do |dat|
50
54
  date, txid = LucaSupport::Code.decode_id(dat[:id])
51
55
  {}.tap do |res|
52
- res['code'] = dat[:code]
56
+ res['code'] = dat[:code].length == 1 ? dat[:code].first : dat[:code]
53
57
  res['date'] = date
54
58
  res['no'] = txid
55
59
  res['id'] = dat[:id]
@@ -99,30 +103,22 @@ module LucaBook #:nodoc:
99
103
 
100
104
  private
101
105
 
102
- def set_balance
106
+ def set_balance(recursive = false)
103
107
  return BigDecimal('0') if @code.nil? || /^[A-H]/.match(@code)
104
108
 
105
- balance_dict = Dict.latest_balance(@start)
106
- start_balance = BigDecimal(balance_dict.dig(@code.to_s, :balance) || '0')
107
- start = Dict.issue_date(balance_dict)&.next_month
108
- last = @start.prev_month
109
- if last.year >= start.year && last.month >= start.month
110
- start_balance + self.class.term(start.year, start.month, last.year, last.month, code: @code).accumulate_code
111
- else
112
- start_balance
113
- end
109
+ LucaBook::State.start_balance(@start.year, @start.month, recursive: recursive)
114
110
  end
115
111
 
116
- def calc_code
117
- @balance = set_balance
112
+ def calc_code(recursive: false)
113
+ @balance = set_balance(recursive)[@code] || BigDecimal('0')
118
114
  if @code
119
115
  balance = @balance
120
116
  @data.each do |dat|
121
117
  dat[:diff] = Util.diff_by_code(dat[:debit], @code) - Util.diff_by_code(dat[:credit], @code)
122
118
  balance += dat[:diff]
123
119
  dat[:balance] = balance
124
- dat[:code] = @code
125
- counter = dat[:diff] * Util.pn_debit(@code) > 0 ? :credit : :debit
120
+ target, counter = dat[:diff] * Util.pn_debit(@code) > 0 ? [:debit, :credit] : [:credit, :debit]
121
+ dat[:code] = dat[target].map { |d| d[:code] }
126
122
  dat[:counter_code] = dat[counter].map { |d| d[:code] }
127
123
  end
128
124
  end
@@ -132,7 +128,7 @@ module LucaBook #:nodoc:
132
128
  def convert_label
133
129
  @data.each do |dat|
134
130
  if @code
135
- dat[:code] = "#{dat[:code]} #{@@dict.dig(dat[:code], :label)}"
131
+ dat[:code] = dat[:code].map { |target| "#{target} #{@@dict.dig(target, :label)}" }
136
132
  dat[:counter_code] = dat[:counter_code].map { |counter| "#{counter} #{@@dict.dig(counter, :label)}" }
137
133
  else
138
134
  dat[:debit].each { |debit| debit[:code] = "#{debit[:code]} #{@@dict.dig(debit[:code], :label)}" }
@@ -27,7 +27,7 @@ module LucaBook
27
27
  @count = count
28
28
  @start_date = start_d
29
29
  @end_date = end_d
30
- @start_balance = set_balance
30
+ set_balance
31
31
  end
32
32
 
33
33
  def self.range(from_year, from_month, to_year = from_year, to_month = from_month)
@@ -50,25 +50,29 @@ module LucaBook
50
50
  )
51
51
  end
52
52
 
53
- def self.by_code(code, from_year, from_month, to_year = from_year, to_month = from_month)
53
+ def self.by_code(code, from_year, from_month, to_year = from_year, to_month = from_month, recursive: false)
54
54
  code = search_code(code) if code
55
55
  date = Date.new(from_year.to_i, from_month.to_i, -1)
56
56
  last_date = Date.new(to_year.to_i, to_month.to_i, -1)
57
57
  raise 'invalid term specified' if date > last_date
58
58
 
59
- reports = [].tap do |r|
59
+ balance = start_balance(date.year, date.month, recursive: recursive)[code] || 0
60
+ first_line = { 'code' => nil, 'label' => nil, 'debit_amount' => nil, 'debit_count' => nil, 'credit_amount' => nil, 'credit_count' => nil, 'net' => nil, 'balance' => balance, '_d' => nil }
61
+ reports = [first_line].tap do |r|
60
62
  while date <= last_date do
61
63
  diff = {}.tap do |h|
62
- g = gross(date.year, date.month, code: code)
64
+ g = gross(date.year, date.month, code: code, recursive: recursive)
63
65
  sum = g.dig(:debit).nil? ? BigDecimal('0') : Util.calc_diff(g[:debit], code)
64
66
  sum -= g.dig(:credit).nil? ? BigDecimal('0') : Util.calc_diff(g[:credit], code)
67
+ balance += sum
65
68
  h['code'] = code
66
- h['label'] = LucaRecord::Dict.load('base.tsv').dig(code, :label)
67
- h['net'] = sum
69
+ h['label'] = @@dict.dig(code, :label)
68
70
  h['debit_amount'] = g[:debit]
69
71
  h['debit_count'] = g[:debit_count]
70
72
  h['credit_amount'] = g[:credit]
71
73
  h['credit_count'] = g[:credit_count]
74
+ h['net'] = sum
75
+ h['balance'] = balance
72
76
  h['_d'] = date.to_s
73
77
  end
74
78
  r << diff
@@ -205,25 +209,28 @@ module LucaBook
205
209
  end
206
210
 
207
211
  def set_balance
208
- pre_last = @start_date.prev_month
209
- start_year = if @start_date.month > CONFIG['fy_start'].to_i
210
- pre_last.year
211
- else
212
- pre_last.year - 1
213
- end
214
- pre = self.class.accumulate_term(start_year, CONFIG['fy_start'], pre_last.year, pre_last.month)
215
-
216
- base = Dict.latest_balance(@start_date).each_with_object({}) do |(k, v), h|
212
+ @start_balance = self.class.start_balance(@start_date.year, @start_date.month)
213
+ end
214
+
215
+ def self.start_balance(year, month, recursive: true)
216
+ start_date = Date.new(year, month, 1)
217
+ base = Dict.latest_balance(start_date).each_with_object({}) do |(k, v), h|
217
218
  h[k] = BigDecimal(v[:balance].to_s) if v[:balance]
218
219
  h[k] ||= BigDecimal('0') if k.length == 2
219
220
  end
220
- if pre
221
- idx = (pre.keys + base.keys).uniq
222
- base = {}.tap do |h|
223
- idx.each { |k| h[k] = (base[k] || BigDecimal('0')) + (pre[k] || BigDecimal('0')) }
221
+ if month == CONFIG['fy_start'].to_i
222
+ return recursive ? total_subaccount(base) : base
223
+ end
224
+
225
+ pre_last = start_date.prev_month
226
+ year -= 1 if month <= CONFIG['fy_start'].to_i
227
+ pre = accumulate_term(year, CONFIG['fy_start'], pre_last.year, pre_last.month)
228
+ total = {}.tap do |h|
229
+ (pre.keys + base.keys).uniq.each do |k|
230
+ h[k] = (base[k] || BigDecimal('0')) + (pre[k] || BigDecimal('0'))
224
231
  end
225
232
  end
226
- self.class.total_subaccount(base)
233
+ recursive ? total_subaccount(total) : total
227
234
  end
228
235
 
229
236
  def render_xbrl(filename = nil)
@@ -24,7 +24,7 @@ module LucaBook
24
24
 
25
25
  def amount_by_code(items, code)
26
26
  items
27
- .select { |item| item.dig(:code) == code }
27
+ .select { |item| /^#{code}/.match(item[:code]) }
28
28
  .inject(BigDecimal('0')) { |sum, item| sum + item[:amount] }
29
29
  end
30
30
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LucaBook
4
- VERSION = '0.2.26'
4
+ VERSION = '0.2.27'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lucabook
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.26
4
+ version: 0.2.27
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chuma Takahiro