class LucaBook::Import
Constants
- CREDIT_DEFAULT
- DEBIT_DEFAULT
Public Class Methods
import_json(io)
click to toggle source
JSON Format:¶ ↑
[ { "date": "2020-05-04", "debit" : [ { "label": "savings accounts", "amount": 20000 } ], "credit" : [ { "label": "trade notes receivable", "amount": 20000 } ], "note": "settlement for the last month trade" } ]
# File lib/luca_book/import.rb, line 51 def self.import_json(io) JSON.parse(io).each do |d| code_map = LucaRecord::Dict.reverse(LucaRecord::Dict.load('base.tsv')) d['debit'].each { |h| h['code'] = code_map.dig(h['label']) || DEBIT_DEFAULT } d['credit'].each { |h| h['code'] = code_map.dig(h['label']) || CREDIT_DEFAULT } LucaBook::Journal.create(d) end end
new(path, dict)
click to toggle source
# File lib/luca_book/import.rb, line 20 def initialize(path, dict) raise 'no such file' unless FileTest.file?(path) @target_file = path # TODO: yaml need to be configurable @dict_name = dict @dict = LucaBook::Dict.new("import-#{dict}.yaml") @code_map = LucaRecord::Dict.reverse(LucaRecord::Dict.load('base.tsv')) @config = @dict.csv_config if dict end
Public Instance Methods
import_csv()
click to toggle source
# File lib/luca_book/import.rb, line 61 def import_csv @dict.load_csv(@target_file) do |row| if @config[:type] == 'single' LucaBook::Journal.create(parse_single(row)) elsif @config[:type] == 'double' p parse_double(row) # TODO: Not implemented yet else p row end end end
tax_extension(code1, code2, amount, options)
click to toggle source
TODO: need to be separated into pluggable l10n module. TODO: gensen rate >1m yen. TODO: gensen & consumption `round()` rules need to be confirmed. Profit or Loss account should be specified as code1.
# File lib/luca_book/import_jp.rb, line 14 def tax_extension(code1, code2, amount, options) return nil if options.nil? || options[:tax_options].nil? return nil if !options[:tax_options].include?('jp-gensen') && !options[:tax_options].include?('jp-consumption') gensen_rate = BigDecimal('0.1021') consumption_rate = BigDecimal('0.1') gensen_code = @code_map.dig(options[:gensen_label]) || @code_map.dig('預り金') gensen_idx = /^[5-8B-G]/.match(code1) ? 1 : 0 consumption_idx = /^[A-G]/.match(code1) ? 0 : 1 consumption_code = @code_map.dig(options[:consumption_label]) consumption_code ||= /^[A]/.match(code1) ? @code_map.dig('仮受消費税等') : @code_map.dig('仮払消費税等') if options[:tax_options].include?('jp-gensen') && options[:tax_options].include?('jp-consumption') paid_rate = BigDecimal('1') + consumption_rate - gensen_rate gensen_amount = (amount / paid_rate * gensen_rate).round consumption_amount = (amount / paid_rate * consumption_rate).round [].tap do |res| res << [].tap do |res1| amount1 = amount amount1 -= consumption_amount if consumption_idx == 0 amount1 += gensen_amount if gensen_idx == 1 res1 << { 'code' => code1, 'amount' => amount1 } res1 << { 'code' => consumption_code, 'amount' => consumption_amount } if consumption_idx == 0 res1 << { 'code' => gensen_code, 'amount' => gensen_amount } if gensen_idx == 0 end res << [].tap do |res2| amount2 = amount amount2 -= consumption_amount if consumption_idx == 1 amount2 += gensen_amount if gensen_idx == 0 res2 << { 'code' => code2, 'amount' => amount2 } res2 << { 'code' => consumption_code, 'amount' => consumption_amount } if consumption_idx == 1 res2 << { 'code' => gensen_code, 'amount' => gensen_amount } if gensen_idx == 1 end end elsif options[:tax_options].include?('jp-gensen') paid_rate = BigDecimal('1') - gensen_rate gensen_amount = (amount / paid_rate * gensen_rate).round [].tap do |res| res << [].tap do |res1| amount1 = amount amount1 += gensen_amount if gensen_idx == 1 res1 << { 'code' => code, 'amount' => amount1 } res1 << { 'code' => gensen_code, 'amount' => gensen_amount } if gensen_idx == 0 end res << [].tap do |res2| amount2 = amount amount2 += gensen_amount if gensen_idx == 0 mount2 ||= amount res2 << { 'code' => code2, 'amount' => amount2 } res2 << { 'code' => gensen_code, 'amount' => gensen_amount } if gensen_idx == 1 end end elsif options[:tax_options].include?('jp-consumption') paid_rate = BigDecimal('1') + consumption_rate - gensen_rate consumption_amount = (amount / paid_rate * consumption_rate).round res << [].tap do |res1| amount1 = amount amount1 -= consumption_amount if consumption_idx == 0 res1 << { 'code' => code1, 'amount' => amount1 } res1 << { 'code' => consumption_code, 'amount' => consumption_amount } if consumption_idx == 0 end res << [].tap do |res2| amount2 = amount amount2 -= consumption_amount if consumption_idx == 1 res2 << { 'code' => code2, 'amount' => amount2 } res2 << { 'code' => consumption_code, 'amount' => consumption_amount } if consumption_idx == 1 end end end
Private Instance Methods
parse_date(row)
click to toggle source
# File lib/luca_book/import.rb, line 131 def parse_date(row) return nil if row.dig(@config[:year]).empty? "#{row.dig(@config[:year])}-#{row.dig(@config[:month])}-#{row.dig(@config[:day])}" end
parse_double(row)
click to toggle source
convert double entry data
# File lib/luca_book/import.rb, line 110 def parse_double(row) {}.tap do |d| d['date'] = parse_date(row) d['debit'] = { 'code' => search_code(row[@config[:label]], @config.dig(:default_debit)) || DEBIT_DEFAULT, 'amount' => row.dig(@config[:debit_amount]) } d['credit'] = { 'code' => search_code(row[@config[:label]], @config.dig(:default_credit)) || CREDIT_DEFAULT, 'amount' => row.dig(@config[:credit_amount]) } d['note'] = Array(@config[:note]).map{ |col| row[col] }.join(' ') d['x-editor'] = "LucaBook::Import/#{@dict_name}" end end
parse_single(row)
click to toggle source
convert single entry data
# File lib/luca_book/import.rb, line 77 def parse_single(row) if (row.dig(@config[:credit_amount]) || []).empty? amount = BigDecimal(row[@config[:debit_amount]]) debit = true else amount = BigDecimal(row[@config[:credit_amount]]) end default_label = debit ? @config.dig(:default_debit) : @config.dig(:default_credit) code, options = search_code(row[@config[:label]], default_label, amount) counter_code = @code_map.dig(@config[:counter_label]) if options x_customer = options[:'x-customer'] if options[:'x-customer'] data, data_c = tax_extension(code, counter_code, amount, options) if respond_to? :tax_extension end data ||= [{ 'code' => code, 'amount' => amount }] data_c ||= [{ 'code' => counter_code, 'amount' => amount }] {}.tap do |d| d['date'] = parse_date(row) if debit d['debit'] = data d['credit'] = data_c else d['debit'] = data_c d['credit'] = data end d['note'] = Array(@config[:note]).map{ |col| row[col] }.join(' ') d['headers'] = { 'x-editor' => "LucaBook::Import/#{@dict_name}" } d['headers']['x-customer'] = x_customer if x_customer end end
search_code(label, default_label, amount = nil)
click to toggle source
# File lib/luca_book/import.rb, line 126 def search_code(label, default_label, amount = nil) label, options = @dict.search(label, default_label, amount) [@code_map.dig(label), options] end