lucabook 0.2.21 → 0.2.26
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/exe/luca-book +76 -7
- data/lib/luca_book.rb +2 -0
- data/lib/luca_book/accumulator.rb +152 -0
- data/lib/luca_book/console.rb +4 -4
- data/lib/luca_book/dict.rb +168 -4
- data/lib/luca_book/import.rb +36 -37
- data/lib/luca_book/import_jp.rb +83 -0
- data/lib/luca_book/journal.rb +98 -23
- data/lib/luca_book/list.rb +32 -17
- data/lib/luca_book/list_by_header.rb +120 -0
- data/lib/luca_book/setup.rb +2 -1
- data/lib/luca_book/state.rb +142 -217
- data/lib/luca_book/templates/base-jp.xbrl.erb +23 -48
- data/lib/luca_book/templates/base-jp.xsd.erb +17 -0
- data/lib/luca_book/templates/config.yml +4 -0
- data/lib/luca_book/templates/dict-en.tsv +45 -50
- data/lib/luca_book/templates/dict-jp-edinet.tsv +167 -0
- data/lib/luca_book/templates/dict-jp.tsv +192 -162
- data/lib/luca_book/templates/monthly-report.html.erb +67 -0
- data/lib/luca_book/version.rb +1 -1
- metadata +10 -3
data/lib/luca_book/import.rb
CHANGED
@@ -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 =
|
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
|
@@ -30,13 +35,13 @@ module LucaBook
|
|
30
35
|
# "debit" : [
|
31
36
|
# {
|
32
37
|
# "label": "savings accounts",
|
33
|
-
# "
|
38
|
+
# "amount": 20000
|
34
39
|
# }
|
35
40
|
# ],
|
36
41
|
# "credit" : [
|
37
42
|
# {
|
38
43
|
# "label": "trade notes receivable",
|
39
|
-
# "
|
44
|
+
# "amount": 20000
|
40
45
|
# }
|
41
46
|
# ],
|
42
47
|
# "note": "settlement for the last month trade"
|
@@ -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,41 @@ 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
|
-
|
78
|
+
if (row.dig(@config[:credit_amount]) || []).empty?
|
79
|
+
amount = BigDecimal(row[@config[:debit_amount]])
|
80
|
+
debit = true
|
81
|
+
else
|
82
|
+
amount = BigDecimal(row[@config[:credit_amount]])
|
83
|
+
end
|
84
|
+
default_label = debit ? @config.dig(:default_debit) : @config.dig(:default_credit)
|
85
|
+
code, options = search_code(row[@config[:label]], default_label, amount)
|
86
|
+
counter_code = @code_map.dig(@config[:counter_label])
|
87
|
+
if options
|
88
|
+
x_customer = options[:'x-customer'] if options[:'x-customer']
|
89
|
+
data, data_c = tax_extension(code, counter_code, amount, options) if respond_to? :tax_extension
|
90
|
+
end
|
91
|
+
data ||= [{ 'code' => code, 'amount' => amount }]
|
92
|
+
data_c ||= [{ 'code' => counter_code, 'amount' => amount }]
|
85
93
|
{}.tap do |d|
|
86
94
|
d['date'] = parse_date(row)
|
87
|
-
if
|
88
|
-
d['debit'] =
|
89
|
-
|
90
|
-
]
|
91
|
-
d['credit'] = [
|
92
|
-
{ 'code' => @code_map.dig(@config[:counter_label]) }
|
93
|
-
]
|
95
|
+
if debit
|
96
|
+
d['debit'] = data
|
97
|
+
d['credit'] = data_c
|
94
98
|
else
|
95
|
-
d['debit'] =
|
96
|
-
|
97
|
-
]
|
98
|
-
d['credit'] = [
|
99
|
-
{ 'code' => search_code(row[@config[:label]], @config.dig(:default_credit)) || CREDIT_DEFAULT }
|
100
|
-
]
|
99
|
+
d['debit'] = data_c
|
100
|
+
d['credit'] = data
|
101
101
|
end
|
102
|
-
d['debit'][0]['value'] = value
|
103
|
-
d['credit'][0]['value'] = value
|
104
102
|
d['note'] = Array(@config[:note]).map{ |col| row[col] }.join(' ')
|
105
|
-
d['x-editor'
|
103
|
+
d['headers'] = { 'x-editor' => "LucaBook::Import/#{@dict_name}" }
|
104
|
+
d['headers']['x-customer'] = x_customer if x_customer
|
106
105
|
end
|
107
106
|
end
|
108
107
|
|
109
|
-
#
|
110
108
|
# convert double entry data
|
111
109
|
#
|
112
110
|
def parse_double(row)
|
@@ -114,19 +112,20 @@ module LucaBook
|
|
114
112
|
d['date'] = parse_date(row)
|
115
113
|
d['debit'] = {
|
116
114
|
'code' => search_code(row[@config[:label]], @config.dig(:default_debit)) || DEBIT_DEFAULT,
|
117
|
-
'
|
115
|
+
'amount' => row.dig(@config[:debit_amount])
|
118
116
|
}
|
119
117
|
d['credit'] = {
|
120
118
|
'code' => search_code(row[@config[:label]], @config.dig(:default_credit)) || CREDIT_DEFAULT,
|
121
|
-
'
|
119
|
+
'amount' => row.dig(@config[:credit_amount])
|
122
120
|
}
|
123
121
|
d['note'] = Array(@config[:note]).map{ |col| row[col] }.join(' ')
|
124
122
|
d['x-editor'] = "LucaBook::Import/#{@dict_name}"
|
125
123
|
end
|
126
124
|
end
|
127
125
|
|
128
|
-
def search_code(label, default_label)
|
129
|
-
@
|
126
|
+
def search_code(label, default_label, amount = nil)
|
127
|
+
label, options = @dict.search(label, default_label, amount)
|
128
|
+
[@code_map.dig(label), options]
|
130
129
|
end
|
131
130
|
|
132
131
|
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, 'amount' => amount1 }
|
35
|
+
res1 << { 'code' => consumption_code, 'amount' => consumption_amount } if consumption_idx == 0
|
36
|
+
res1 << { 'code' => gensen_code, 'amount' => 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, 'amount' => amount2 }
|
43
|
+
res2 << { 'code' => consumption_code, 'amount' => consumption_amount } if consumption_idx == 1
|
44
|
+
res2 << { 'code' => gensen_code, 'amount' => 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, 'amount' => amount1 }
|
55
|
+
res1 << { 'code' => gensen_code, 'amount' => 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, 'amount' => amount2 }
|
62
|
+
res2 << { 'code' => gensen_code, 'amount' => 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, 'amount' => amount1 }
|
72
|
+
res1 << { 'code' => consumption_code, 'amount' => 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, 'amount' => amount2 }
|
78
|
+
res2 << { 'code' => consumption_code, 'amount' => consumption_amount } if consumption_idx == 1
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/lib/luca_book/journal.rb
CHANGED
@@ -1,43 +1,90 @@
|
|
1
|
-
#
|
2
|
-
# manipulate files based on transaction date
|
3
|
-
#
|
1
|
+
# frozen_string_literal: true
|
4
2
|
|
5
3
|
require 'csv'
|
6
4
|
require 'date'
|
7
5
|
require 'luca_record'
|
8
6
|
|
9
|
-
module LucaBook
|
7
|
+
module LucaBook #:nodoc:
|
8
|
+
# Journal has several annotations on headers:
|
9
|
+
#
|
10
|
+
# x-customer::
|
11
|
+
# Identifying customer.
|
12
|
+
# x-editor::
|
13
|
+
# Application name editing the journal.
|
14
|
+
# x-tax::
|
15
|
+
# For tracking tax related transaction.
|
16
|
+
#
|
10
17
|
class Journal < LucaRecord::Base
|
18
|
+
ACCEPTED_HEADERS = ['x-customer', 'x-editor', 'x-tax']
|
11
19
|
@dirname = 'journals'
|
12
20
|
|
13
21
|
# create journal from hash
|
14
22
|
#
|
15
|
-
def self.create(
|
23
|
+
def self.create(dat)
|
24
|
+
d = LucaSupport::Code.keys_stringify(dat)
|
25
|
+
validate(d)
|
26
|
+
raise 'NoDateKey' unless d.key?('date')
|
27
|
+
|
16
28
|
date = Date.parse(d['date'])
|
17
29
|
|
18
|
-
|
19
|
-
|
30
|
+
# TODO: need to sync filename & content. Limit code length for filename
|
31
|
+
# codes = (debit_code + credit_code).uniq
|
32
|
+
codes = nil
|
33
|
+
|
34
|
+
create_record(nil, date, codes) { |f| f.write journal2csv(d) }
|
35
|
+
end
|
36
|
+
|
37
|
+
# update journal with hash.
|
38
|
+
# If record not found with id, no record will be created.
|
39
|
+
#
|
40
|
+
def self.save(dat)
|
41
|
+
d = LucaSupport::Code.keys_stringify(dat)
|
42
|
+
raise 'record has no id.' if d['id'].nil?
|
43
|
+
|
44
|
+
validate(d)
|
45
|
+
parts = d['id'].split('/')
|
46
|
+
raise 'invalid ID' if parts.length != 2
|
47
|
+
|
48
|
+
codes = nil
|
49
|
+
open_records(@dirname, parts[0], parts[1], codes, 'w') { |f, _path| f.write journal2csv(d) }
|
50
|
+
end
|
51
|
+
|
52
|
+
# Convert journal object to TSV format.
|
53
|
+
#
|
54
|
+
def self.journal2csv(d)
|
55
|
+
debit_amount = LucaSupport::Code.decimalize(serialize_on_key(d['debit'], 'amount'))
|
56
|
+
credit_amount = LucaSupport::Code.decimalize(serialize_on_key(d['credit'], 'amount'))
|
20
57
|
raise 'BalanceUnmatch' if debit_amount.inject(:+) != credit_amount.inject(:+)
|
21
58
|
|
22
59
|
debit_code = serialize_on_key(d['debit'], 'code')
|
23
60
|
credit_code = serialize_on_key(d['credit'], 'code')
|
24
61
|
|
25
|
-
|
26
|
-
# codes = (debit_code + credit_code).uniq
|
27
|
-
codes = nil
|
28
|
-
create_record!(date, codes) do |f|
|
62
|
+
csv = CSV.generate(String.new, col_sep: "\t", headers: false) do |f|
|
29
63
|
f << debit_code
|
30
64
|
f << LucaSupport::Code.readable(debit_amount)
|
31
65
|
f << credit_code
|
32
66
|
f << LucaSupport::Code.readable(credit_amount)
|
33
|
-
|
34
|
-
f << [x_header, d[x_header]] if d.dig(x_header)
|
67
|
+
ACCEPTED_HEADERS.each do |x_header|
|
68
|
+
f << [x_header, d['headers'][x_header]] if d.dig('headers', x_header)
|
35
69
|
end
|
36
70
|
f << []
|
37
71
|
f << [d.dig('note')]
|
38
72
|
end
|
39
73
|
end
|
40
74
|
|
75
|
+
# Set accepted header with key/value, update record if exists.
|
76
|
+
#
|
77
|
+
def self.add_header(journal_hash, key, val)
|
78
|
+
return journal_hash if val.nil?
|
79
|
+
return journal_hash unless ACCEPTED_HEADERS.include?(key)
|
80
|
+
|
81
|
+
journal_hash.tap do |o|
|
82
|
+
o[:headers] = {} unless o.dig(:headers)
|
83
|
+
o[:headers][key] = val
|
84
|
+
save o if o[:id]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
41
88
|
def self.update_codes(obj)
|
42
89
|
debit_code = serialize_on_key(obj[:debit], :code)
|
43
90
|
credit_code = serialize_on_key(obj[:credit], :code)
|
@@ -45,11 +92,19 @@ module LucaBook
|
|
45
92
|
change_codes(obj[:id], codes)
|
46
93
|
end
|
47
94
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
95
|
+
def self.validate(obj)
|
96
|
+
raise 'NoDebitKey' unless obj.key?('debit')
|
97
|
+
raise 'NoCreditKey' unless obj.key?('credit')
|
98
|
+
debit_codes = serialize_on_key(obj['debit'], 'code').compact
|
99
|
+
debit_amount = serialize_on_key(obj['debit'], 'amount').compact
|
100
|
+
raise 'NoDebitCode' if debit_codes.empty?
|
101
|
+
raise 'NoDebitAmount' if debit_amount.empty?
|
102
|
+
raise 'UnmatchDebit' if debit_codes.length != debit_amount.length
|
103
|
+
credit_codes = serialize_on_key(obj['credit'], 'code').compact
|
104
|
+
credit_amount = serialize_on_key(obj['credit'], 'amount').compact
|
105
|
+
raise 'NoCreditCode' if credit_codes.empty?
|
106
|
+
raise 'NoCreditAmount' if credit_amount.empty?
|
107
|
+
raise 'UnmatchCredit' if credit_codes.length != credit_amount.length
|
53
108
|
end
|
54
109
|
|
55
110
|
# collect values on specified key
|
@@ -58,7 +113,21 @@ module LucaBook
|
|
58
113
|
array_of_hash.map { |h| h[key] }
|
59
114
|
end
|
60
115
|
|
61
|
-
# override de-serializing journal format
|
116
|
+
# override de-serializing journal format. Sample format is:
|
117
|
+
#
|
118
|
+
# {
|
119
|
+
# id: '2021A/V001',
|
120
|
+
# headers: {
|
121
|
+
# 'x-customer' => 'Some Customer Co.'
|
122
|
+
# },
|
123
|
+
# debit: [
|
124
|
+
# { code: 'A12', amount: 1000 }
|
125
|
+
# ],
|
126
|
+
# credit: [
|
127
|
+
# { code: '311', amount: 1000 }
|
128
|
+
# ],
|
129
|
+
# note: 'note for each journal'
|
130
|
+
# }
|
62
131
|
#
|
63
132
|
def self.load_data(io, path)
|
64
133
|
{}.tap do |record|
|
@@ -76,10 +145,16 @@ module LucaBook
|
|
76
145
|
when 3
|
77
146
|
line.each_with_index { |amount, j| record[:credit][j][:amount] = BigDecimal(amount.to_s) }
|
78
147
|
else
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
148
|
+
case body
|
149
|
+
when false
|
150
|
+
if line.empty?
|
151
|
+
record[:note] ||= []
|
152
|
+
body = true
|
153
|
+
else
|
154
|
+
record[:headers] ||= {}
|
155
|
+
record[:headers][line[0]] = line[1]
|
156
|
+
end
|
157
|
+
when true
|
83
158
|
record[:note] << line.join(' ') if body
|
84
159
|
end
|
85
160
|
end
|
data/lib/luca_book/list.rb
CHANGED
@@ -7,20 +7,22 @@ require 'luca_record'
|
|
7
7
|
require 'luca_record/dict'
|
8
8
|
require 'luca_book'
|
9
9
|
|
10
|
-
|
11
|
-
#
|
12
|
-
|
10
|
+
module LucaBook #:nodoc:
|
11
|
+
# Journal List on specified term
|
12
|
+
#
|
13
13
|
class List < LucaBook::Journal
|
14
14
|
@dirname = 'journals'
|
15
|
+
@@dict = LucaRecord::Dict.new('base.tsv')
|
16
|
+
attr_reader :data
|
15
17
|
|
16
18
|
def initialize(data, start_date, code = nil)
|
17
19
|
@data = data
|
18
20
|
@code = code
|
19
21
|
@start = start_date
|
20
|
-
@dict = LucaRecord::Dict.load('base.tsv')
|
21
22
|
end
|
22
23
|
|
23
24
|
def self.term(from_year, from_month, to_year = from_year, to_month = from_month, code: nil, basedir: @dirname)
|
25
|
+
code = search_code(code) if code
|
24
26
|
data = LucaBook::Journal.term(from_year, from_month, to_year, to_month, code).select do |dat|
|
25
27
|
if code.nil?
|
26
28
|
true
|
@@ -31,7 +33,17 @@ module LucaBook
|
|
31
33
|
new data, Date.new(from_year.to_i, from_month.to_i, 1), code
|
32
34
|
end
|
33
35
|
|
34
|
-
def
|
36
|
+
def self.add_header(from_year, from_month, to_year = from_year, to_month = from_month, code: nil, header_key: nil, header_val: nil)
|
37
|
+
return nil if code.nil?
|
38
|
+
return nil unless Journal::ACCEPTED_HEADERS.include?(header_key)
|
39
|
+
|
40
|
+
term(from_year, from_month, to_year, to_month, code: code)
|
41
|
+
.data.each do |journal|
|
42
|
+
Journal.add_header(journal, header_key, header_val)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def list_by_code
|
35
47
|
calc_code
|
36
48
|
convert_label
|
37
49
|
@data = [code_header] + @data.map do |dat|
|
@@ -59,7 +71,7 @@ module LucaBook
|
|
59
71
|
res['no'] = txid
|
60
72
|
res['id'] = dat[:id]
|
61
73
|
res['debit_code'] = dat[:debit].length == 1 ? dat[:debit][0][:code] : dat[:debit].map { |d| d[:code] }
|
62
|
-
res['debit_amount'] =
|
74
|
+
res['debit_amount'] = dat[:debit].inject(0) { |sum, d| sum + d[:amount] }
|
63
75
|
res['credit_code'] = dat[:credit].length == 1 ? dat[:credit][0][:code] : dat[:credit].map { |d| d[:code] }
|
64
76
|
res['credit_amount'] = dat[:credit].inject(0) { |sum, d| sum + d[:amount] }
|
65
77
|
res['note'] = dat[:note]
|
@@ -74,8 +86,15 @@ module LucaBook
|
|
74
86
|
end
|
75
87
|
end
|
76
88
|
|
77
|
-
def
|
78
|
-
|
89
|
+
def self.search_code(code)
|
90
|
+
return code if @@dict.dig(code)
|
91
|
+
|
92
|
+
@@dict.search(code).tap do |new_code|
|
93
|
+
if new_code.nil?
|
94
|
+
puts "Search word is not matched with labels"
|
95
|
+
exit 1
|
96
|
+
end
|
97
|
+
end
|
79
98
|
end
|
80
99
|
|
81
100
|
private
|
@@ -83,7 +102,7 @@ module LucaBook
|
|
83
102
|
def set_balance
|
84
103
|
return BigDecimal('0') if @code.nil? || /^[A-H]/.match(@code)
|
85
104
|
|
86
|
-
balance_dict = Dict.latest_balance
|
105
|
+
balance_dict = Dict.latest_balance(@start)
|
87
106
|
start_balance = BigDecimal(balance_dict.dig(@code.to_s, :balance) || '0')
|
88
107
|
start = Dict.issue_date(balance_dict)&.next_month
|
89
108
|
last = @start.prev_month
|
@@ -113,20 +132,16 @@ module LucaBook
|
|
113
132
|
def convert_label
|
114
133
|
@data.each do |dat|
|
115
134
|
if @code
|
116
|
-
dat[:code] = "#{dat[:code]} #{
|
117
|
-
dat[:counter_code] = dat[:counter_code].map { |counter| "#{counter} #{
|
135
|
+
dat[:code] = "#{dat[:code]} #{@@dict.dig(dat[:code], :label)}"
|
136
|
+
dat[:counter_code] = dat[:counter_code].map { |counter| "#{counter} #{@@dict.dig(counter, :label)}" }
|
118
137
|
else
|
119
|
-
dat[:debit].each { |debit| debit[:code] = "#{debit[:code]} #{
|
120
|
-
dat[:credit].each { |credit| credit[:code] = "#{credit[:code]} #{
|
138
|
+
dat[:debit].each { |debit| debit[:code] = "#{debit[:code]} #{@@dict.dig(debit[:code], :label)}" }
|
139
|
+
dat[:credit].each { |credit| credit[:code] = "#{credit[:code]} #{@@dict.dig(credit[:code], :label)}" }
|
121
140
|
end
|
122
141
|
end
|
123
142
|
self
|
124
143
|
end
|
125
144
|
|
126
|
-
def dict
|
127
|
-
LucaBook::Dict::Data
|
128
|
-
end
|
129
|
-
|
130
145
|
def code_header
|
131
146
|
{}.tap do |h|
|
132
147
|
%w[code date no id diff balance counter_code note].each do |k|
|