lucabook 0.2.12 → 0.2.15

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: 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