lucabook 0.2.12 → 0.2.15

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: b58568499ebfa245c9f86863537eb2a9b26e563ac20a09583a3b12e29bc713a2
4
- data.tar.gz: 77a382f306e0c269182caca7d48bb6fd8d4f6513664d8cef36a28356cacd8998
3
+ metadata.gz: db7564331de8046e8a6507c2ccf7dc099382ff3fc1c6a603f9ecc290755398ba
4
+ data.tar.gz: 5fb64e6fbccc5a5e693211ae89d8bad6560593add1f26261879b2ae4bc67fa00
5
5
  SHA512:
6
- metadata.gz: 1526e2b525c357dc06f87253095a8e8434bacc03994432f90dec6571f4bde9fe24b9d1a81ab3b9747a3d45be767022bb9bf64f1a0b88b298e6997bbb95ca4fd2
7
- data.tar.gz: 111d7eff70797d30bc2df769cbd3d1c8c8b83d92ef5bba8ffa74b60bc06fa9f0754fd54d507f556f7c9831c87a418113ecc797755436f84926e8df88cf117622
6
+ metadata.gz: 4cee8065abe4d479dc909e2e9f12f0fdb942e7b3c51b2f5f5e993598080db28411625d990c7f7a7ec85ebc96686a4dcf6d0173e8fed58fd3a3261731ea3da831
7
+ data.tar.gz: 1cd81e73a4dfcf3eef52a8105b7e1dc921f9d79d8b9945bf2b9e74d80134d2ca157346d69d98a26037d0f087fa4475e05938ae0044a7b1fcb3120b744f3a9ba8
@@ -2,71 +2,87 @@
2
2
 
3
3
  require 'optparse'
4
4
  require 'luca_book'
5
- require 'luca_book/console'
6
5
 
7
- def import(args, params)
8
- if params['config']
9
- LucaBook::Import.new(args[0], params['config']).import_csv
10
- else
11
- puts 'Usage: luca-book import -c import_config'
12
- end
6
+ module LucaCmd
7
+ class Journal
8
+ def self.import(args, params)
9
+ if params['config']
10
+ LucaBook::Import.new(args[0], params['config']).import_csv
11
+ elsif params['json']
12
+ LucaBook::Import.import_json(STDIN.read)
13
+ else
14
+ puts 'Usage: luca-book import -c import_config'
15
+ end
16
+ end
13
17
 
14
- def list(args, params)
15
- if params['c'] or params['code']
16
- code = params['c'] || params['code']
17
- LucaBookConsole.new.by_code(code, args.dig(0), args.dig(1))
18
- elsif args.length > 0
19
- LucaBookConsole.new.by_month(args[0], args.dig(1))
20
- else
21
- LucaBookConsole.new.all
18
+ def self.list(args, params)
19
+ if params['code']
20
+ LucaBook::List.term(*args, code: params['code']).flat_list.to_yaml
21
+ elsif args.length > 0
22
+ LucaBook::List.term(*args).flat_list.to_yaml
23
+ else
24
+ # TODO: define default function
25
+ end
26
+ end
22
27
  end
23
- end
24
28
 
25
- def report(args, params)
26
- if params['bs']
27
- LucaBook::State.term(*args).bs.to_yaml
28
- elsif params['pl']
29
- LucaBook::State.term(*args).pl.to_yaml
30
- else
31
- LucaBook::State.term(*args).to_yaml
29
+ class Report
30
+ def self.balancesheet(args, params)
31
+ LucaBook::State.term(*args).bs.to_yaml
32
+ end
33
+
34
+ def self.profitloss(args, params)
35
+ LucaBook::State.term(*args).pl.to_yaml
36
+ end
32
37
  end
33
38
  end
34
39
 
40
+
35
41
  LucaRecord::Base.valid_project?
36
42
  cmd = ARGV.shift
43
+ params = {}
37
44
 
38
45
  case cmd
39
- when 'import'
40
- params = {}
41
- OptionParser.new do |opt|
42
- opt.banner = 'Usage: luca import filepath'
43
- opt.on('-c', '--config VAL', 'import definition'){|v| params["config"] = v }
44
- args = opt.parse!(ARGV)
45
- import(args, params)
46
- end
47
- when 'list'
48
- params = {}
49
- OptionParser.new do |opt|
50
- opt.banner = 'Usage: luca list [year month]'
51
- opt.on('-c', '--code VAL', 'search with code'){|v| params["code"] = v }
52
- opt.on_tail('List records. If you specify code and/or month, search on each criteria.')
53
- args = opt.parse!(ARGV)
54
- list(args, params)
46
+ when /journals?/, 'j'
47
+ subcmd = ARGV.shift
48
+ case subcmd
49
+ when 'import'
50
+ OptionParser.new do |opt|
51
+ opt.banner = 'Usage: luca import filepath'
52
+ opt.on('-c', '--config VAL', 'import definition'){|v| params['config'] = v }
53
+ opt.on('-j', '--json', 'import via json format'){|_v| params['json'] = true }
54
+ args = opt.parse!(ARGV)
55
+ LucaCmd::Journal.import(args, params)
56
+ end
57
+ when 'list'
58
+ OptionParser.new do |opt|
59
+ opt.banner = 'Usage: luca list [year month]'
60
+ opt.on('-c', '--code VAL', 'search with code') { |v| params['code'] = v }
61
+ opt.on_tail('List records. If you specify code and/or month, search on each criteria.')
62
+ args = opt.parse!(ARGV)
63
+ LucaCmd::Journal.list(args, params)
64
+ end
55
65
  end
56
- when 'report'
57
- params = {}
58
- OptionParser.new do |opt|
59
- opt.banner = 'Usage: luca-book report'
60
- opt.on('--bs', 'show Balance sheet'){|v| params["bs"] = v }
61
- opt.on('--pl', 'show Income statement'){|v| params["pl"] = v }
62
- args = opt.parse!(ARGV)
63
- report(args, params)
66
+ when /reports?/, 'r'
67
+ subcmd = ARGV.shift
68
+ case subcmd
69
+ when 'bs'
70
+ OptionParser.new do |opt|
71
+ opt.banner = 'Usage: luca-book reports bs'
72
+ args = opt.parse!(ARGV)
73
+ LucaCmd::Report.balancesheet(args, params)
74
+ end
75
+ when 'pl'
76
+ OptionParser.new do |opt|
77
+ opt.banner = 'Usage: luca-book reports pl'
78
+ args = opt.parse!(ARGV)
79
+ LucaCmd::Report.profitloss(args, params)
80
+ end
64
81
  end
65
82
  when '--help'
66
83
  puts 'Usage: luca-book subcommand'
67
- puts ' import: import records'
68
- puts ' list: list records'
69
- puts ' report: show reports'
84
+ puts ' journals: operate journal records'
85
+ puts ' reports: show reports'
70
86
  else
71
87
  puts 'Invalid subcommand'
72
88
  end
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'csv'
3
4
  require 'luca_record'
4
5
  require 'luca_book/version'
5
6
 
6
7
  module LucaBook
7
8
  autoload :Import, 'luca_book/import'
8
9
  autoload :Journal, 'luca_book/journal'
10
+ autoload :List, 'luca_book/list'
9
11
  autoload :Setup, 'luca_book/setup'
10
12
  autoload :State, 'luca_book/state'
11
13
  end
@@ -1,25 +1,15 @@
1
1
  require 'luca_book'
2
2
 
3
+ # This class will be deleted
4
+ #
3
5
  class LucaBookConsole
4
6
 
5
7
  def initialize(dir_path=nil)
6
- @report = LucaBookReport.new(dir_path)
8
+ @report = LucaBook::State.new(dir_path)
7
9
  end
8
10
 
9
- def all
10
- array = @report.scan_terms(@report.book.pjdir).map{|y,m| y}.uniq.map{|year|
11
- @report.book.search(year)
12
- }.flatten
13
- show_records(array)
14
- end
15
-
16
- def by_code(code, year=nil, month=nil)
17
- array = @report.by_code(code, year, month)
18
- show_records(array)
19
- end
20
-
21
- def by_month(year, month)
22
- array = @report.book.search(year, month)
11
+ def by_term(year, month, end_year = year, end_month = month)
12
+ array = @report.book.class.term(year, month, end_year, end_month)
23
13
  show_records(array)
24
14
  end
25
15
 
@@ -19,36 +19,39 @@ module LucaBook
19
19
  # TODO: yaml need to be configurable
20
20
  @dict = LucaRecord::Dict.new("import-#{dict}.yaml")
21
21
  @code_map = LucaRecord::Dict.reverse(LucaRecord::Dict.load('base.tsv'))
22
- @config = @dict.csv_config
22
+ @config = @dict.csv_config if dict
23
23
  end
24
24
 
25
25
  # === JSON Format:
26
- # {
27
- # "date": "2020-05-04",
28
- # "debit" : [
29
- # {
30
- # "label": "savings accounts",
31
- # "value": 20000
32
- # }
33
- # ],
34
- # "credit" : [
35
- # {
36
- # "label": "trade notes receivable",
37
- # "value": 20000
38
- # }
39
- # ],
40
- # "note": "settlement for the last month trade"
41
- # }
26
+ # [
27
+ # {
28
+ # "date": "2020-05-04",
29
+ # "debit" : [
30
+ # {
31
+ # "label": "savings accounts",
32
+ # "value": 20000
33
+ # }
34
+ # ],
35
+ # "credit" : [
36
+ # {
37
+ # "label": "trade notes receivable",
38
+ # "value": 20000
39
+ # }
40
+ # ],
41
+ # "note": "settlement for the last month trade"
42
+ # }
43
+ # ]
42
44
  #
43
- def import_json(io)
44
- d = JSON.parse(io)
45
- validate(d)
45
+ def self.import_json(io)
46
+ JSON.parse(io).each do |d|
47
+ validate(d)
46
48
 
47
- # dict = LucaBook::Dict.reverse_dict(LucaBook::Dict::Data)
48
- d['debit'].each { |h| h['code'] = @dict.search(h['label'], DEBIT_DEFAULT) }
49
- d['credit'].each { |h| h['code'] = @dict.search(h['label'], CREDIT_DEFAULT) }
49
+ code_map = LucaRecord::Dict.reverse(LucaRecord::Dict.load('base.tsv'))
50
+ d['debit'].each { |h| h['code'] = code_map.dig(h['label']) || DEBIT_DEFAULT }
51
+ d['credit'].each { |h| h['code'] = code_map.dig(h['label']) || CREDIT_DEFAULT }
50
52
 
51
- LucaBook.new.create(d)
53
+ LucaBook::Journal.create(d)
54
+ end
52
55
  end
53
56
 
54
57
  def import_csv
@@ -63,6 +66,16 @@ module LucaBook
63
66
  end
64
67
  end
65
68
 
69
+ def self.validate(obj)
70
+ raise 'NoDateKey' unless obj.key?('date')
71
+ raise 'NoDebitKey' unless obj.key?('debit')
72
+ raise 'NoDebitValue' if obj['debit'].empty?
73
+ raise 'NoCreditKey' unless obj.key?('credit')
74
+ raise 'NoCreditValue' if obj['credit'].empty?
75
+ end
76
+
77
+ private
78
+
66
79
  #
67
80
  # convert single entry data
68
81
  #
@@ -87,7 +100,7 @@ module LucaBook
87
100
  end
88
101
  d['debit'][0]['value'] = value
89
102
  d['credit'][0]['value'] = value
90
- d['note'] = row[@config[:note]]
103
+ d['note'] = Array(@config[:note]).map{ |col| row[col] }.join(' ')
91
104
  end
92
105
  end
93
106
 
@@ -105,7 +118,7 @@ module LucaBook
105
118
  'code' => search_code(row[@config[:credit_label]], CREDIT_DEFAULT),
106
119
  'value' => row.dig(@config[:credit_value])
107
120
  }
108
- d['note'] = row[@config[:note]]
121
+ d['note'] = Array(@config[:note]).map{ |col| row[col] }.join(' ')
109
122
  end
110
123
  end
111
124
 
@@ -118,13 +131,5 @@ module LucaBook
118
131
 
119
132
  "#{row.dig(@config[:year])}-#{row.dig(@config[:month])}-#{row.dig(@config[:day])}"
120
133
  end
121
-
122
- def validate(obj)
123
- raise 'NoDateKey' if ! obj.has_key?('date')
124
- raise 'NoDebitKey' if ! obj.has_key?('debit')
125
- raise 'NoDebitValue' if obj['debit'].length < 1
126
- raise 'NoCreditKey' if ! obj.has_key?('credit')
127
- raise 'NoCreditValue' if obj['credit'].length < 1
128
- end
129
134
  end
130
135
  end
@@ -30,6 +30,9 @@ module LucaBook
30
30
  f << LucaSupport::Code.readable(debit_amount)
31
31
  f << credit_code
32
32
  f << LucaSupport::Code.readable(credit_amount)
33
+ ['x-customer', 'x-editor'].each do |x_header|
34
+ f << [x_header, d[x_header]] if d.dig(x_header)
35
+ end
33
36
  f << []
34
37
  f << [d.dig('note')]
35
38
  end
@@ -80,8 +83,8 @@ module LucaBook
80
83
  record[:note] << line.join(' ') if body
81
84
  end
82
85
  end
83
- record[:note]&.join('\n')
84
86
  end
87
+ record[:note] = record[:note]&.join('\n')
85
88
  end
86
89
  end
87
90
  end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pathname'
4
+ require 'date'
5
+ require 'luca_support'
6
+ require 'luca_record'
7
+ require 'luca_record/dict'
8
+ require 'luca_book'
9
+
10
+ # Journal List on specified term
11
+ #
12
+ module LucaBook
13
+ class List < LucaBook::Journal
14
+ @dirname = 'journals'
15
+
16
+ def initialize(data)
17
+ @data = data
18
+ @dict = LucaRecord::Dict.load('base.tsv')
19
+ end
20
+
21
+ def self.term(from_year, from_month, to_year = from_year, to_month = from_month, code: nil, basedir: @dirname)
22
+ data = LucaBook::Journal.term(from_year, from_month, to_year, to_month, code).select do |dat|
23
+ if code.nil?
24
+ true
25
+ else
26
+ [:debit, :credit].map { |key| serialize_on_key(dat[key], :code) }.flatten.include?(code)
27
+ end
28
+ end
29
+ new data
30
+ end
31
+
32
+ def convert_label
33
+ @data.each do |dat|
34
+ dat[:debit].each { |debit| debit[:code] = "#{debit[:code]} #{@dict.dig(debit[:code], :label)}" }
35
+ dat[:credit].each { |credit| credit[:code] = "#{credit[:code]} #{@dict.dig(credit[:code], :label)}" }
36
+ end
37
+ self
38
+ end
39
+
40
+ def flat_list
41
+ convert_label
42
+ @data = @data.map do |dat|
43
+ idx = dat[:debit].length >= dat[:credit].length ? :debit : :credit
44
+ dat[idx].map.with_index do |_k, i|
45
+ date, txid = LucaSupport::Code.decode_id(dat[:id])
46
+ {}.tap do |res|
47
+ res['date'] = date
48
+ res['no'] = txid
49
+ res['id'] = dat[:id]
50
+ res['debit_code'] = dat[:debit][i][:code] if dat[:debit][i]
51
+ res['debit_amount'] = dat[:debit][i][:amount] if dat[:debit][i]
52
+ res['credit_code'] = dat[:credit][i][:code] if dat[:credit][i]
53
+ res['credit_amount'] = dat[:credit][i][:amount] if dat[:credit][i]
54
+ res['note'] = dat[:note]
55
+ end
56
+ end
57
+ end.flatten
58
+ self
59
+ end
60
+
61
+ def to_yaml
62
+ YAML.dump(LucaSupport::Code.readable(@data)).tap { |data| puts data }
63
+ end
64
+
65
+ def dict
66
+ LucaBook::Dict::Data
67
+ end
68
+ end
69
+ end
@@ -51,18 +51,18 @@ module LucaBook
51
51
  end
52
52
 
53
53
  def by_code(code, year=nil, month=nil)
54
- raise "not supported year range yet" if ! year.nil? && month.nil?
54
+ raise 'not supported year range yet' if ! year.nil? && month.nil?
55
55
 
56
- bl = @book.load_start.dig(code) || 0
57
- full_term = scan_terms(LucaSupport::Config::Pjdir)
56
+ balance = @book.load_start.dig(code) || 0
57
+ full_term = self.class.scan_terms
58
58
  if ! month.nil?
59
- pre_term = full_term.select{|y,m| y <= year.to_i && m < month.to_i }
60
- bl += pre_term.map{|y,m| self.class.net(y, m)}.inject(0){|sum, h| sum + h[code]}
61
- [{ code: code, balance: bl, note: "#{code} #{dict.dig(code, :label)}" }] + records_with_balance(year, month, code, bl)
59
+ pre_term = full_term.select { |y, m| y <= year.to_i && m < month.to_i }
60
+ balance += pre_term.map { |y, m| self.class.net(y, m)}.inject(0){|sum, h| sum + h[code] }
61
+ [{ code: code, balance: balance, note: "#{code} #{dict.dig(code, :label)}" }] + records_with_balance(year, month, code, balance)
62
62
  else
63
- start = { code: code, balance: bl, note: "#{code} #{dict.dig(code, :label)}" }
64
- full_term.map {|y, m| y }.uniq.map {|y|
65
- records_with_balance(y, nil, code, bl)
63
+ start = { code: code, balance: balance, note: "#{code} #{dict.dig(code, :label)}" }
64
+ full_term.map { |y, m| y }.uniq.map { |y|
65
+ records_with_balance(y, nil, code, balance)
66
66
  }.flatten.prepend(start)
67
67
  end
68
68
  end
@@ -81,7 +81,7 @@ module LucaBook
81
81
  current = @book.load_start
82
82
  target = []
83
83
  Dir.chdir(@book.pjdir) do
84
- net_records = scan_terms(@book.pjdir).map do |year, month|
84
+ net_records = self.class.scan_terms.map do |year, month|
85
85
  target << [year, month]
86
86
  accumulate_month(year, month)
87
87
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LucaBook
4
- VERSION = '0.2.12'
4
+ VERSION = '0.2.15'
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.12
4
+ version: 0.2.15
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-09 00:00:00.000000000 Z
11
+ date: 2020-11-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lucarecord
@@ -83,6 +83,7 @@ files:
83
83
  - lib/luca_book/dict.rb
84
84
  - lib/luca_book/import.rb
85
85
  - lib/luca_book/journal.rb
86
+ - lib/luca_book/list.rb
86
87
  - lib/luca_book/report.rb
87
88
  - lib/luca_book/setup.rb
88
89
  - lib/luca_book/state.rb