lucarecord 0.2.13 → 0.2.18
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 +4 -4
- data/CHANGELOG.md +8 -0
- data/lib/luca_record.rb +3 -0
- data/lib/luca_record/dict.rb +2 -2
- data/lib/luca_record/io.rb +161 -127
- data/lib/luca_record/version.rb +1 -1
- data/lib/luca_support/code.rb +49 -4
- data/lib/luca_support/config.rb +10 -1
- metadata +19 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 63ac71426bdf4eb871884b8b28c5aa363db9d51ef3ca0d84ab92a3fcf127ecde
|
4
|
+
data.tar.gz: 2bc0d6ecde974a2f9ca9c901af5ac714c909f40dd84986746948065a4efb4ed7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f9cf84bfb09080f6f3e8cf15c8fb3cea0d6eca9d69acc10c23cd9b6a681daae9ab641181a928f438c870a438a0c4525c61bfad6a1832a2d148b7a3d37b3d6d3
|
7
|
+
data.tar.gz: be35bd6b0a993b5fde415ba5e1a7b59228106c443594b164fa5df26f1eb284ae0556277b99b25f7697283ac194f6c25ffa7d7d8d3e1bfe2e22b128130f3f9cec
|
data/CHANGELOG.md
CHANGED
@@ -0,0 +1,8 @@
|
|
1
|
+
## LucaRecord 0.2.18
|
2
|
+
|
3
|
+
* `find()`, `create()`, `save()` now supports both of uuid / historical records. If specified `date:` keyword option to `create()`, then generate historical record. `find()`, `save()` identifies with 'id' attribute.
|
4
|
+
|
5
|
+
## LucaRecord 0.2.17
|
6
|
+
|
7
|
+
* Change internal number format to BigDecimal.
|
8
|
+
* Number of Decimal is configurable through `decimal_number` in config.yml(default = 2). `country` setting can also affect.
|
data/lib/luca_record.rb
CHANGED
data/lib/luca_record/dict.rb
CHANGED
data/lib/luca_record/io.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bigdecimal'
|
1
4
|
require 'csv'
|
2
5
|
require 'date'
|
3
6
|
require 'fileutils'
|
@@ -6,11 +9,10 @@ require 'pathname'
|
|
6
9
|
require 'luca_support/code'
|
7
10
|
require 'luca_support/config'
|
8
11
|
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
module LucaRecord
|
12
|
+
module LucaRecord # :nodoc:
|
13
|
+
# == IO
|
14
|
+
# Read / Write hash data with id and/or date.
|
15
|
+
# Manage both database & historical records.
|
14
16
|
module IO
|
15
17
|
include LucaSupport::Code
|
16
18
|
|
@@ -18,42 +20,25 @@ module LucaRecord
|
|
18
20
|
klass.extend ClassMethods
|
19
21
|
end
|
20
22
|
|
21
|
-
#
|
22
|
-
# Used @date for searching current settings
|
23
|
-
# query can be nested hash for other than 'val'
|
24
|
-
#
|
25
|
-
# where(contract_status: 'active')
|
26
|
-
# where(graded: {rank: 5})
|
27
|
-
#
|
28
|
-
def where(**query)
|
29
|
-
return enum_for(:where, **query) unless block_given?
|
30
|
-
|
31
|
-
query.each do |key, val|
|
32
|
-
v = val.respond_to?(:values) ? val.values.first : val
|
33
|
-
label = val.respond_to?(:keys) ? val.keys.first : 'val'
|
34
|
-
self.class.all do |data|
|
35
|
-
next unless data.keys.map(&:to_sym).include?(key)
|
36
|
-
|
37
|
-
processed = parse_current(data)
|
38
|
-
yield processed if v == processed.dig(key.to_s, label.to_s)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
23
|
module ClassMethods
|
44
|
-
#
|
24
|
+
# ----------------------------------------------------------------
|
25
|
+
# :section: Query Methods
|
26
|
+
# Provide sematic search interfaces.
|
27
|
+
# <tt>basedir</tt> is set by class instance variable <tt>@dirname</tt>
|
28
|
+
# of each concrete class.
|
29
|
+
# ----------------------------------------------------------------
|
30
|
+
|
45
31
|
# find ID based record. Support uuid and encoded date.
|
46
|
-
#
|
47
32
|
def find(id, basedir = @dirname)
|
48
|
-
return enum_for(:find, id, basedir) unless block_given?
|
33
|
+
return enum_for(:find, id, basedir).first unless block_given?
|
49
34
|
|
50
35
|
if id.length >= 40
|
51
36
|
open_hashed(basedir, id) do |f|
|
52
37
|
yield load_data(f)
|
53
38
|
end
|
54
|
-
elsif id.length >=
|
55
|
-
|
56
|
-
open_records(basedir,
|
39
|
+
elsif id.length >= 7
|
40
|
+
parts = id.split('/')
|
41
|
+
open_records(basedir, parts[0], parts[1]) do |f, path|
|
57
42
|
yield load_data(f, path)
|
58
43
|
end
|
59
44
|
else
|
@@ -61,7 +46,6 @@ module LucaRecord
|
|
61
46
|
end
|
62
47
|
end
|
63
48
|
|
64
|
-
#
|
65
49
|
# search date based record.
|
66
50
|
#
|
67
51
|
# * data hash
|
@@ -75,7 +59,6 @@ module LucaRecord
|
|
75
59
|
end
|
76
60
|
end
|
77
61
|
|
78
|
-
#
|
79
62
|
# search with date params & code.
|
80
63
|
#
|
81
64
|
def search(year, month = nil, day = nil, code = nil, basedir = @dirname)
|
@@ -91,103 +74,155 @@ module LucaRecord
|
|
91
74
|
end
|
92
75
|
end
|
93
76
|
|
94
|
-
#
|
95
77
|
# retrieve all data
|
96
78
|
#
|
97
79
|
def all(basedir = @dirname)
|
98
80
|
return enum_for(:all, basedir) unless block_given?
|
99
81
|
|
100
|
-
open_all(basedir) do |f|
|
82
|
+
open_all(basedir) do |f|
|
101
83
|
yield load_data(f)
|
102
84
|
end
|
103
85
|
end
|
104
86
|
|
87
|
+
# ----------------------------------------------------------------
|
88
|
+
# :section: Write Methods
|
89
|
+
# <tt>basedir</tt> is set by class instance variable <tt>@dirname</tt>
|
90
|
+
# of each concrete class.
|
91
|
+
# ----------------------------------------------------------------
|
92
|
+
|
93
|
+
# create record both of uuid/date identified.
|
105
94
|
#
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
# * "a7b806d04a044c6dbc4ce72932867719"
|
111
|
-
#
|
112
|
-
def id2path(id)
|
113
|
-
if id.is_a?(Array)
|
114
|
-
id.join('/')
|
115
|
-
elsif id.include?('/')
|
116
|
-
id
|
95
|
+
def create(obj, date: nil, codes: nil, basedir: @dirname)
|
96
|
+
validate_keys(obj)
|
97
|
+
if date
|
98
|
+
create_record(obj, date, codes, basedir)
|
117
99
|
else
|
118
|
-
|
100
|
+
obj['id'] = LucaSupport::Code.issue_random_id
|
101
|
+
open_hashed(basedir, obj['id'], 'w') do |f|
|
102
|
+
f.write(YAML.dump(LucaSupport::Code.readable(obj.sort.to_h)))
|
103
|
+
end
|
104
|
+
obj['id']
|
119
105
|
end
|
120
106
|
end
|
121
107
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
len = id.length
|
127
|
-
if len <= split_factor
|
128
|
-
['', id]
|
129
|
-
else
|
130
|
-
[id[0, split_factor], id[split_factor, len - split_factor]]
|
131
|
-
end
|
108
|
+
def prepare_dir!(basedir, date_obj)
|
109
|
+
dir_name = (Pathname(basedir) + LucaSupport::Code.encode_dirname(date_obj)).to_s
|
110
|
+
FileUtils.mkdir_p(dir_name) unless Dir.exist?(dir_name)
|
111
|
+
dir_name
|
132
112
|
end
|
133
113
|
|
134
114
|
def add_status!(id, status, basedir = @dirname)
|
135
115
|
path = abs_path(basedir) / id2path(id)
|
136
|
-
origin = YAML.load_file(path, {})
|
116
|
+
origin = YAML.load_file(path, **{})
|
137
117
|
newline = { status => DateTime.now.to_s }
|
138
118
|
origin['status'] = [] if origin['status'].nil?
|
139
119
|
origin['status'] << newline
|
140
120
|
File.write(path, YAML.dump(origin.sort.to_h))
|
141
121
|
end
|
142
122
|
|
143
|
-
#
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
123
|
+
# update file with obj['id']
|
124
|
+
def save(obj, basedir = @dirname)
|
125
|
+
if obj['id'].nil?
|
126
|
+
create(obj, basedir)
|
127
|
+
else
|
128
|
+
validate_keys(obj)
|
129
|
+
if obj['id'].length < 40
|
130
|
+
parts = obj['id'].split('/')
|
131
|
+
raise 'invalid ID' if parts.length != 2
|
132
|
+
|
133
|
+
open_records(basedir, parts[0], parts[1], nil, 'w') do |f, path|
|
134
|
+
f.write(YAML.dump(LucaSupport::Code.readable(obj.sort.to_h)))
|
135
|
+
end
|
136
|
+
else
|
137
|
+
open_hashed(basedir, obj['id'], 'w') do |f|
|
138
|
+
f.write(YAML.dump(LucaSupport::Code.readable(obj.sort.to_h)))
|
139
|
+
end
|
140
|
+
end
|
151
141
|
end
|
142
|
+
obj['id']
|
143
|
+
end
|
144
|
+
|
145
|
+
# delete file by id
|
146
|
+
def delete(id, basedir = @dirname)
|
147
|
+
FileUtils.rm(Pathname(abs_path(basedir)) / id2path(id))
|
152
148
|
id
|
153
149
|
end
|
154
150
|
|
151
|
+
# ----------------------------------------------------------------
|
152
|
+
# :section: Path Utilities
|
153
|
+
# ----------------------------------------------------------------
|
154
|
+
|
155
|
+
# Convert ID to file directory/filename path.
|
156
|
+
# 1st element of Array is used as directory, the others as filename.
|
157
|
+
# String without '/' is converted as git-like structure.
|
158
|
+
# Normal argument is as follows:
|
155
159
|
#
|
156
|
-
#
|
157
|
-
#
|
158
|
-
|
159
|
-
|
160
|
-
|
160
|
+
# ['2020H', 'V001', 'a7b806d04a044c6dbc4ce72932867719']
|
161
|
+
# => '2020H/V001-a7b806d04a044c6dbc4ce72932867719'
|
162
|
+
# 'a7b806d04a044c6dbc4ce72932867719'
|
163
|
+
# => 'a7b/806d04a044c6dbc4ce72932867719'
|
164
|
+
# '2020H/V001'
|
165
|
+
# => '2020H/V001'
|
166
|
+
def id2path(id)
|
167
|
+
if id.is_a?(Array)
|
168
|
+
case id.length
|
169
|
+
when 0..2
|
170
|
+
id.join('/')
|
171
|
+
else
|
172
|
+
[id[0], id[1..-1].join('-')].join('/')
|
173
|
+
end
|
174
|
+
elsif id.include?('/')
|
175
|
+
id
|
176
|
+
else
|
177
|
+
encode_hashed_path(id).join('/')
|
161
178
|
end
|
162
179
|
end
|
163
180
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
if
|
168
|
-
|
181
|
+
# Directory separation for performance. Same as Git way.
|
182
|
+
def encode_hashed_path(id, split_factor = 3)
|
183
|
+
len = id.length
|
184
|
+
if len <= split_factor
|
185
|
+
['', id]
|
186
|
+
else
|
187
|
+
[id[0, split_factor], id[split_factor, len - split_factor]]
|
169
188
|
end
|
170
|
-
path = Pathname(d) + filename
|
171
|
-
File.open(path.to_s, 'w') { |f| yield(f) }
|
172
189
|
end
|
173
190
|
|
174
|
-
|
175
|
-
|
191
|
+
# test if having required dirs/files under exec path
|
192
|
+
def valid_project?(path = LucaSupport::Config::Pjdir)
|
193
|
+
project_dir = Pathname(path)
|
194
|
+
FileTest.file?((project_dir + 'config.yml').to_s) and FileTest.directory?( (project_dir + 'data').to_s)
|
176
195
|
end
|
177
196
|
|
178
|
-
def
|
179
|
-
|
180
|
-
FileUtils.mkdir_p(dir_name) unless Dir.exist?(dir_name)
|
181
|
-
dir_name
|
182
|
-
end
|
183
|
-
|
184
|
-
def encode_dirname(date_obj)
|
185
|
-
date_obj.year.to_s + LucaSupport::Code.encode_month(date_obj)
|
197
|
+
def new_record_id(basedir, date_obj)
|
198
|
+
LucaSupport::Code.encode_txid(new_record_no(basedir, date_obj))
|
186
199
|
end
|
187
200
|
|
188
201
|
private
|
189
202
|
|
203
|
+
# define new transaction ID & write data at once
|
204
|
+
# ID format is like '2020H/A001', which means record no.1 of 2020/10/10.
|
205
|
+
# Any data format can be written with block.
|
190
206
|
#
|
207
|
+
def create_record(obj, date_obj, codes = nil, basedir = @dirname)
|
208
|
+
FileUtils.mkdir_p(abs_path(basedir)) unless Dir.exist?(abs_path(basedir))
|
209
|
+
subdir = "#{date_obj.year}#{LucaSupport::Code.encode_month(date_obj)}"
|
210
|
+
filename = LucaSupport::Code.encode_date(date_obj) + new_record_id(basedir, date_obj)
|
211
|
+
obj['id'] = "#{subdir}/#{filename}" if obj.is_a? Hash
|
212
|
+
filename += '-' + codes.join('-') if codes
|
213
|
+
Dir.chdir(abs_path(basedir)) do
|
214
|
+
FileUtils.mkdir_p(subdir) unless Dir.exist?(subdir)
|
215
|
+
File.open(Pathname(subdir) / filename, 'w') do |f|
|
216
|
+
if block_given?
|
217
|
+
yield(f)
|
218
|
+
else
|
219
|
+
f.write(YAML.dump(LucaSupport::Code.readable(obj.sort.to_h)))
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
"#{subdir}/#{filename}"
|
224
|
+
end
|
225
|
+
|
191
226
|
# open records with 'basedir/month/date-code' path structure.
|
192
227
|
# Glob pattern can be specified like folloing examples.
|
193
228
|
#
|
@@ -198,12 +233,12 @@ module LucaRecord
|
|
198
233
|
# 1. encoded month
|
199
234
|
# 2. encoded day + record number of the day
|
200
235
|
# 3. codes. More than 3 are all code set except first 2 parameters.
|
201
|
-
#
|
202
236
|
def open_records(basedir, subdir, filename = nil, code = nil, mode = 'r')
|
203
237
|
return enum_for(:open_records, basedir, subdir, filename, code, mode) unless block_given?
|
204
238
|
|
205
239
|
file_pattern = filename.nil? ? '*' : "#{filename}*"
|
206
240
|
Dir.chdir(abs_path(basedir)) do
|
241
|
+
FileUtils.mkdir_p(subdir) if mode == 'w' && !Dir.exist?(subdir)
|
207
242
|
Dir.glob("#{subdir}*/#{file_pattern}").sort.each do |subpath|
|
208
243
|
next if skip_on_unmatch_code(subpath, code)
|
209
244
|
|
@@ -213,7 +248,6 @@ module LucaRecord
|
|
213
248
|
end
|
214
249
|
end
|
215
250
|
|
216
|
-
#
|
217
251
|
# git object like structure
|
218
252
|
#
|
219
253
|
def open_hashed(basedir, id, mode = 'r')
|
@@ -225,7 +259,6 @@ module LucaRecord
|
|
225
259
|
File.open((dirpath + filename).to_s, mode) { |f| yield f }
|
226
260
|
end
|
227
261
|
|
228
|
-
#
|
229
262
|
# scan through all files
|
230
263
|
#
|
231
264
|
def open_all(basedir, mode = 'r')
|
@@ -237,7 +270,6 @@ module LucaRecord
|
|
237
270
|
end
|
238
271
|
end
|
239
272
|
|
240
|
-
#
|
241
273
|
# Decode basic format.
|
242
274
|
# If specific decode is needed, override this method in each class.
|
243
275
|
#
|
@@ -249,7 +281,18 @@ module LucaRecord
|
|
249
281
|
when 'json'
|
250
282
|
# TODO: implement JSON parse
|
251
283
|
else
|
252
|
-
YAML.load(io.read)
|
284
|
+
YAML.load(io.read).tap { |obj| validate_keys(obj) }
|
285
|
+
.inject({}) { |h, (k, v)| h[k] = LucaSupport::Code.decimalize(v); h }
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
def validate_keys(obj)
|
290
|
+
return nil unless @required
|
291
|
+
|
292
|
+
keys = obj.keys
|
293
|
+
[].tap do |errors|
|
294
|
+
@required.each { |r| errors << r unless keys.include?(r) }
|
295
|
+
raise "Missing keys: #{errors.join(' ')}" unless errors.empty?
|
253
296
|
end
|
254
297
|
end
|
255
298
|
|
@@ -270,8 +313,10 @@ module LucaRecord
|
|
270
313
|
|
271
314
|
# AUTO INCREMENT
|
272
315
|
def new_record_no(basedir, date_obj)
|
273
|
-
|
274
|
-
|
316
|
+
raise 'No target dir exists.' unless Dir.exist?(abs_path(basedir))
|
317
|
+
|
318
|
+
dir_name = (Pathname(abs_path(basedir)) / LucaSupport::Code.encode_dirname(date_obj)).to_s
|
319
|
+
return 1 unless Dir.exist?(dir_name)
|
275
320
|
|
276
321
|
Dir.chdir(dir_name) do
|
277
322
|
last_file = Dir.glob("#{LucaSupport::Code.encode_date(date_obj)}*").max
|
@@ -282,25 +327,28 @@ module LucaRecord
|
|
282
327
|
end
|
283
328
|
end # end of ClassModules
|
284
329
|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
330
|
+
# Used @date for searching current settings
|
331
|
+
# query can be nested hash for other than 'val'
|
332
|
+
#
|
333
|
+
# where(contract_status: 'active')
|
334
|
+
# where(graded: {rank: 5})
|
335
|
+
#
|
336
|
+
def where(**query)
|
337
|
+
return enum_for(:where, **query) unless block_given?
|
293
338
|
|
294
|
-
|
295
|
-
|
339
|
+
query.each do |key, val|
|
340
|
+
v = val.respond_to?(:values) ? val.values.first : val
|
341
|
+
label = val.respond_to?(:keys) ? val.keys.first : 'val'
|
342
|
+
self.class.all do |data|
|
343
|
+
next unless data.keys.map(&:to_sym).include?(key)
|
296
344
|
|
297
|
-
|
298
|
-
|
299
|
-
|
345
|
+
processed = parse_current(data)
|
346
|
+
yield processed if v == processed.dig(key.to_s, label.to_s)
|
347
|
+
end
|
348
|
+
end
|
300
349
|
end
|
301
350
|
|
302
|
-
#
|
303
|
-
# for date based records
|
351
|
+
# parse data dir and respond existing months
|
304
352
|
#
|
305
353
|
def scan_terms(base_dir, query = nil)
|
306
354
|
pattern = query.nil? ? "*" : "#{query}*"
|
@@ -313,25 +361,11 @@ module LucaRecord
|
|
313
361
|
|
314
362
|
def load_config(path = nil)
|
315
363
|
path = path.to_s
|
316
|
-
if File.
|
364
|
+
if File.exist?(path)
|
317
365
|
YAML.load_file(path, **{})
|
318
366
|
else
|
319
367
|
{}
|
320
368
|
end
|
321
369
|
end
|
322
|
-
|
323
|
-
def has_status?(dat, status)
|
324
|
-
return false if dat['status'].nil?
|
325
|
-
|
326
|
-
dat['status'].map { |h| h.key?(status) }
|
327
|
-
.include?(true)
|
328
|
-
end
|
329
|
-
|
330
|
-
def load_tsv(path)
|
331
|
-
return enum_for(:load_tsv, path) unless block_given?
|
332
|
-
|
333
|
-
data = CSV.read(path, headers: true, col_sep: "\t", encoding: 'UTF-8')
|
334
|
-
data.each { |row| yield row }
|
335
|
-
end
|
336
370
|
end
|
337
371
|
end
|
data/lib/luca_record/version.rb
CHANGED
data/lib/luca_support/code.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'date'
|
4
4
|
require 'securerandom'
|
5
5
|
require 'digest/sha1'
|
6
|
+
require 'luca_support/config'
|
6
7
|
|
7
8
|
# implement Luca IDs convention
|
8
9
|
module LucaSupport
|
@@ -12,7 +13,7 @@ module LucaSupport
|
|
12
13
|
def encode_txid(num)
|
13
14
|
txmap = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
14
15
|
l = txmap.length
|
15
|
-
txmap[num / (l**2)] + txmap[(num%(l**2)) / l] + txmap[num % l]
|
16
|
+
txmap[num / (l**2)] + txmap[(num % (l**2)) / l] + txmap[num % l]
|
16
17
|
end
|
17
18
|
|
18
19
|
def decode_txid(id)
|
@@ -44,7 +45,12 @@ module LucaSupport
|
|
44
45
|
num.to_s.reverse.gsub!(/(\d{3})(?=\d)/, '\1,').reverse!
|
45
46
|
end
|
46
47
|
|
48
|
+
# encode directory name from year and month.
|
47
49
|
#
|
50
|
+
def encode_dirname(date_obj)
|
51
|
+
date_obj.year.to_s + encode_month(date_obj)
|
52
|
+
end
|
53
|
+
|
48
54
|
# Month to code conversion.
|
49
55
|
# Date, DateTime, String, Integer is valid input. If nil, returns empty String for consistency.
|
50
56
|
#
|
@@ -72,8 +78,40 @@ module LucaSupport
|
|
72
78
|
Digest::SHA1.hexdigest(SecureRandom.uuid)
|
73
79
|
end
|
74
80
|
|
81
|
+
def decimalize(obj)
|
82
|
+
case obj.class.name
|
83
|
+
when 'Array'
|
84
|
+
obj.map { |i| decimalize(i) }
|
85
|
+
when 'Hash'
|
86
|
+
obj.inject({}) { |h, (k, v)| h[k] = decimalize(v); h }
|
87
|
+
when 'Integer'
|
88
|
+
BigDecimal(obj.to_s)
|
89
|
+
when 'String'
|
90
|
+
/^[0-9\.]+$/.match(obj) ? BigDecimal(obj) : obj
|
91
|
+
when 'Float'
|
92
|
+
raise 'already float'
|
93
|
+
else
|
94
|
+
obj
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def readable(obj, len = LucaSupport::Config::DECIMAL_NUM)
|
99
|
+
case obj.class.name
|
100
|
+
when 'Array'
|
101
|
+
obj.map { |i| readable(i) }
|
102
|
+
when 'Hash'
|
103
|
+
obj.inject({}) { |h, (k, v)| h[k] = readable(v); h }
|
104
|
+
when 'BigDecimal'
|
105
|
+
parts = obj.round(len).to_s('F').split('.')
|
106
|
+
len < 1 ? parts.first : "#{parts[0]}.#{parts[1][0, len]}"
|
107
|
+
else
|
108
|
+
obj
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
75
112
|
#
|
76
|
-
# convert effective/defunct data into current hash on @date
|
113
|
+
# convert effective/defunct data into current hash on @date.
|
114
|
+
# not parse nested children.
|
77
115
|
#
|
78
116
|
def parse_current(dat)
|
79
117
|
{}.tap do |processed|
|
@@ -92,11 +130,11 @@ module LucaSupport
|
|
92
130
|
# - effective: 2020-1-1
|
93
131
|
# rank: 5
|
94
132
|
# point: 1000
|
95
|
-
# => { 'effective' => 2020-1-1, 'rank' => 5, '
|
133
|
+
# => { 'effective' => 2020-1-1, 'rank' => 5, 'point' => 1000 }
|
96
134
|
#
|
97
135
|
def take_current(dat, item)
|
98
136
|
target = dat.dig(item)
|
99
|
-
if target.
|
137
|
+
if target.is_a?(Array) && target.map(&:keys).flatten.include?('effective')
|
100
138
|
latest = target
|
101
139
|
.filter { |a| Date.parse(a.dig('effective').to_s) < @date }
|
102
140
|
.max { |a, b| Date.parse(a.dig('effective').to_s) <=> Date.parse(b.dig('effective').to_s) }
|
@@ -107,5 +145,12 @@ module LucaSupport
|
|
107
145
|
target
|
108
146
|
end
|
109
147
|
end
|
148
|
+
|
149
|
+
def has_status?(dat, status)
|
150
|
+
return false if dat['status'].nil?
|
151
|
+
|
152
|
+
dat['status'].map { |h| h.key?(status) }
|
153
|
+
.include?(true)
|
154
|
+
end
|
110
155
|
end
|
111
156
|
end
|
data/lib/luca_support/config.rb
CHANGED
@@ -1,11 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'pathname'
|
4
|
+
require 'yaml'
|
5
|
+
|
3
6
|
#
|
4
7
|
# startup config
|
5
8
|
#
|
6
9
|
module LucaSupport
|
7
10
|
module Config
|
8
11
|
# Project top directory.
|
9
|
-
Pjdir = Dir.pwd.freeze
|
12
|
+
Pjdir = ENV['LUCA_TEST_DIR'] || Dir.pwd.freeze
|
13
|
+
if File.exist?(Pathname(Pjdir) / 'config.yml')
|
14
|
+
DECIMAL_NUM = YAML.load_file(Pathname(Pjdir) / 'config.yml', **{})['decimal_number']
|
15
|
+
COUNTRY = YAML.load_file(Pathname(Pjdir) / 'config.yml', **{})['country']
|
16
|
+
DECIMAL_NUM ||= 0 if COUNTRY == 'jp'
|
17
|
+
end
|
18
|
+
DECIMAL_NUM ||= 2
|
10
19
|
end
|
11
20
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lucarecord
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.18
|
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
|
+
date: 2020-11-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mail
|
@@ -28,44 +28,44 @@ dependencies:
|
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '1.17'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.17'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: minitest
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: '5.0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: '5.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 12.3.3
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 12.3.3
|
69
69
|
description: 'ERP File operation framework
|
70
70
|
|
71
71
|
'
|
@@ -87,12 +87,13 @@ files:
|
|
87
87
|
- lib/luca_support/config.rb
|
88
88
|
- lib/luca_support/mail.rb
|
89
89
|
- lib/luca_support/view.rb
|
90
|
-
homepage: https://github.com/chumaltd/luca/lucarecord
|
91
|
-
licenses:
|
90
|
+
homepage: https://github.com/chumaltd/luca/tree/master/lucarecord
|
91
|
+
licenses:
|
92
|
+
- GPL
|
92
93
|
metadata:
|
93
|
-
homepage_uri: https://github.com/chumaltd/luca/lucarecord
|
94
|
-
source_code_uri: https://github.com/chumaltd/luca/lucarecord
|
95
|
-
changelog_uri: https://github.com/chumaltd/luca/lucarecord/CHANGELOG.md
|
94
|
+
homepage_uri: https://github.com/chumaltd/luca/tree/master/lucarecord
|
95
|
+
source_code_uri: https://github.com/chumaltd/luca/tree/master/lucarecord
|
96
|
+
changelog_uri: https://github.com/chumaltd/luca/tree/master/lucarecord/CHANGELOG.md
|
96
97
|
post_install_message:
|
97
98
|
rdoc_options: []
|
98
99
|
require_paths:
|
@@ -101,7 +102,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
101
102
|
requirements:
|
102
103
|
- - ">="
|
103
104
|
- !ruby/object:Gem::Version
|
104
|
-
version:
|
105
|
+
version: 2.6.0
|
105
106
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
106
107
|
requirements:
|
107
108
|
- - ">="
|