Class: LucaBook::Dict
- Inherits:
-
LucaRecord::Dict
- Object
- LucaRecord::Dict
- LucaBook::Dict
- Includes:
- Accumulator, Util, LucaRecord::IO, LucaSupport::Range
- Defined in:
- lib/luca_book/dict.rb
Class Method Summary collapse
- .checksum(start_date, end_date) ⇒ Object
-
.export_balance(date) ⇒ Object
TODO: support date in the middle of month.
- .generate_balance(year, month = nil) ⇒ Object
- .gitref ⇒ Object
- .issue_date(obj) ⇒ Object
-
.latest_balance(date) ⇒ Object
Find balance at financial year start by given date.
- .latest_balance_path(date) ⇒ Object
- .load_balance(start_date, end_date) ⇒ Object
Instance Method Summary collapse
-
#csv_config ⇒ Object
Column number settings for CSV/TSV convert.
-
#filter_amount(settings, amount = nil) ⇒ Object
Choose setting on Big or small condition.
- #search(word, default_word = nil, amount = nil) ⇒ Object
Methods included from Accumulator
#credit_amount, #credit_count, #debit_amount, #debit_count, #each_month, #gross_amount, #gross_count, included, #net_amount
Methods included from Util
amount_by_code, calc_diff, current_fy, diff_by_code, pn_debit, previous_fy, validate_balance
Class Method Details
.checksum(start_date, end_date) ⇒ Object
189 190 191 192 193 194 195 |
# File 'lib/luca_book/dict.rb', line 189 def self.checksum(start_date, end_date) digest = update_digest(String.new, File.read(latest_balance_path(start_date))) term_by_month(start_date, end_date) .map { |date| dir_digest(date.year, date.month) } .each { |month_digest| digest = update_digest(digest, month_digest) } digest end |
.export_balance(date) ⇒ Object
TODO: support date in the middle of month.
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/luca_book/dict.rb', line 144 def self.export_balance(date) start_date, end_date = Util.current_fy(date, to: date) labels = load('base.tsv') bs = load_balance(start_date, end_date) dat = [].tap do |res| item = {} item['date'] = date.to_s item['debit'] = [] item['credit'] = [] bs.each do |code, balance| next if balance.zero? if /^[1-4]/.match(code) item['debit'] << { 'label' => labels.dig(code, :label), 'amount' => LucaSupport::Code.readable(balance) } elsif /^[5-9]/.match(code) item['credit'] << { 'label' => labels.dig(code, :label), 'amount' => LucaSupport::Code.readable(balance) } end end item['x-editor'] = 'LucaBook' res << item end puts JSON.dump(dat) end |
.generate_balance(year, month = nil) ⇒ Object
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/luca_book/dict.rb', line 118 def self.generate_balance(year, month = nil) start_date = Date.new((year.to_i - 1), LucaSupport::CONST.config['fy_start'], 1) month ||= LucaSupport::CONST.config['fy_start'] - 1 end_date = Date.new(year.to_i, month, -1) labels = load('base.tsv') bs = load_balance(start_date, end_date) fy_digest = checksum(start_date, end_date) current_ref = gitref csv = CSV.generate(String.new, col_sep: "\t", headers: false) do |f| f << ['code', 'label', 'balance'] f << ['_date', end_date] f << ['_digest', fy_digest] f << ['_gitref', current_ref] if current_ref bs.each do |code, balance| next if LucaSupport::Code.readable(balance) == 0 f << [code, labels.dig(code, :label), LucaSupport::Code.readable(balance)] end end dict_dir = Pathname(LucaSupport::CONST.pjdir) / 'data' / 'balance' filepath = dict_dir / "start-#{end_date.to_s}.tsv" File.open(filepath, 'w') { |f| f.write csv } end |
.gitref ⇒ Object
197 198 199 200 |
# File 'lib/luca_book/dict.rb', line 197 def self.gitref digest = `git rev-parse HEAD` $?.exitstatus == 0 ? digest.strip : nil end |
.issue_date(obj) ⇒ Object
114 115 116 |
# File 'lib/luca_book/dict.rb', line 114 def self.issue_date(obj) Date.parse(obj.dig('_date', :label)) end |
.latest_balance(date) ⇒ Object
Find balance at financial year start by given date. If not found ‘start-yyyy-mm-*.tsv’, use ‘start.tsv’ as default.
100 101 102 |
# File 'lib/luca_book/dict.rb', line 100 def self.latest_balance(date) load_tsv_dict(latest_balance_path(date)) end |
.latest_balance_path(date) ⇒ Object
104 105 106 107 108 109 110 111 112 |
# File 'lib/luca_book/dict.rb', line 104 def self.latest_balance_path(date) start_date, _ = LucaBook::Util.current_fy(date) dict_dir = Pathname(LucaSupport::CONST.pjdir) / 'data' / 'balance' paths = Dir.glob(%Q(start-*-*-*), base: dict_dir, sort: true) .reject {|path| path > %Q(start-#{start_date.year}-#{format("%02d", start_date.month)}-) } return dict_dir / 'start.tsv' if paths.empty? dict_dir / paths.reverse.first end |
.load_balance(start_date, end_date) ⇒ Object
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/luca_book/dict.rb', line 168 def self.load_balance(start_date, end_date) base = latest_balance(start_date).each_with_object({}) do |(k, v), h| h[k] = BigDecimal(v[:balance].to_s) if v[:balance] end search_range = term_by_month(start_date, end_date) bs = search_range.each_with_object(base) do |date, h| net(date.year, date.month)[0].each do |code, amount| next if /^[^1-9]/.match(code) h[code] ||= BigDecimal('0') h[code] += amount end end bs['9142'] ||= BigDecimal('0') bs['9142'] += LucaBook::State .range(start_date.year, start_date.month, end_date.year, end_date.month) .net_income bs.sort end |
Instance Method Details
#csv_config ⇒ Object
Column number settings for CSV/TSV convert
:label
for double entry data
:counter_label
must be specified with label
:debit_label
for double entry data
-
debit_amount
:credit_label
for double entry data
-
credit_amount
:note
can be the same column as another label
:encoding
file encoding
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/luca_book/dict.rb', line 38 def csv_config {}.tap do |config| if @config.dig('label') config[:label] = @config['label'].to_i if @config.dig('counter_label') config[:counter_label] = @config['counter_label'] config[:type] = 'single' end elsif @config.dig('debit_label') config[:debit_label] = @config['debit_label'].to_i if @config.dig('credit_label') config[:credit_label] = @config['credit_label'].to_i config[:type] = 'double' end end config[:type] ||= 'invalid' config[:debit_amount] = @config['debit_amount'].to_i if @config.dig('debit_amount') config[:credit_amount] = @config['credit_amount'].to_i if @config.dig('credit_amount') config[:note] = @config['note'] if @config.dig('note') config[:encoding] = @config['encoding'] if @config.dig('encoding') config[:year] = @config['year'] if @config.dig('year') config[:month] = @config['month'] if @config.dig('month') config[:day] = @config['day'] if @config.dig('day') config[:default_debit] = @config['default_debit'] if @config.dig('default_debit') config[:default_credit] = @config['default_credit'] if @config.dig('default_credit') end end |
#filter_amount(settings, amount = nil) ⇒ Object
Choose setting on Big or small condition.
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/luca_book/dict.rb', line 78 def filter_amount(settings, amount = nil) return settings[0] if amount.nil? settings.each do |item| return item unless item[1].keys.include?(:on_amount) condition = item.dig(1, :on_amount) case condition[0] when '>' return item if amount > BigDecimal(condition[1..]) when '<' return item if amount < BigDecimal(condition[1..]) else return item end end nil end |
#search(word, default_word = nil, amount = nil) ⇒ Object
67 68 69 70 71 72 73 74 |
# File 'lib/luca_book/dict.rb', line 67 def search(word, default_word = nil, amount = nil) res = super(word, default_word, main_key: 'account_label') if res.is_a?(Array) && res[0].is_a?(Array) filter_amount(res, amount) else res end end |