Class: Iif::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/iif/parser.rb,
lib/iif/parser/version.rb

Constant Summary collapse

VERSION =
"2.0.2"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(resource, opts = {}) ⇒ Parser

Returns a new instance of Parser.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/iif/parser.rb', line 12

def initialize(resource, opts = {})
  @definitions = {}
  @entries = []
  @transactions = []
  unless resource.force_encoding('UTF-8').valid_encoding?
    cd = CharDet.detect(resource)
    resource.encode!("UTF-8", cd["encoding"])
  end
  resource.gsub!(/\r\n?/, "\n") # dos to unix EOL conversion
  resource = open_resource(resource)
  resource.rewind
  parse_file(resource, opts[:csv_parse_line_options] || {})
  create_transactions
end

Instance Attribute Details

#definitionsObject

Returns the value of attribute definitions.



10
11
12
# File 'lib/iif/parser.rb', line 10

def definitions
  @definitions
end

#entriesObject

Returns the value of attribute entries.



10
11
12
# File 'lib/iif/parser.rb', line 10

def entries
  @entries
end

#transactionsObject

Returns the value of attribute transactions.



10
11
12
# File 'lib/iif/parser.rb', line 10

def transactions
  @transactions
end

Instance Method Details

#clean_field(field) ⇒ Object



78
79
80
81
82
# File 'lib/iif/parser.rb', line 78

def clean_field(field)
  field.gsub!(/\A"|"\Z/, '')
  field.strip! if field.is_a?(String)
  field
end

#convert_amount(amount) ⇒ Object



91
92
93
94
95
96
97
98
99
100
# File 'lib/iif/parser.rb', line 91

def convert_amount(amount)
  amount.gsub!(/(,)/,'')
  if amount =~ /^--/
    amount.slice!(0)
  elsif amount =~ /^\(.*\)$/
    amount.gsub!(/[()]/,'')
    amount.prepend("-")
  end
  BigDecimal(amount)
end

#convert_date(date) ⇒ Object



84
85
86
87
88
89
# File 'lib/iif/parser.rb', line 84

def convert_date(date)
  return Date.parse(date) if date =~ /^\d{4}-[01]\d-[0123]\d$/
  ar = date.split(/[-\/]/).map(&:to_i)
  year = ar[2].to_s.size == 4 ? ar[2] : "20#{ar[2]}"
  Date.new(year.to_i, ar[0], ar[1])
end

#create_transactionsObject



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/iif/parser.rb', line 102

def create_transactions
  transaction = nil
  in_transaction = false

  @entries.each do |entry|
    
    case entry.type

    when "TRNS"
      if in_transaction
        @transactions.push(transaction)
        in_transaction = false
      end
      transaction = Transaction.new
      in_transaction = true
      
    when "ENDTRNS"
      @transactions.push(transaction)
      in_transaction = false

    end

    transaction.entries.push(entry) if in_transaction
  end
end

#open_resource(resource) ⇒ Object



27
28
29
30
31
32
33
34
35
# File 'lib/iif/parser.rb', line 27

def open_resource(resource)
  if resource.respond_to?(:read)
    resource
  else
    open(resource)
  end
rescue Exception
  StringIO.new(resource)
end

#parse_data(fields) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/iif/parser.rb', line 65

def parse_data(fields)
  definition = @definitions[fields[0]]
  entry = Entry.new
  entry.type = fields[0]
  fields[1..-1].each_with_index do |field, idx|
    next unless definition and definition[idx]
    entry.send(definition[idx] + "=", field)
  end
  entry.amount = convert_amount(entry.amount) unless entry.amount.to_s == ""
  entry.date = convert_date(entry.date) if entry.date and not entry.date == ""
  @entries.push(entry)
end

#parse_definition(fields) ⇒ Object



59
60
61
62
63
# File 'lib/iif/parser.rb', line 59

def parse_definition(fields)
  key = fields[0][1..-1]
  values = fields[1..-1]
  @definitions[key] = values.map { |v| v.downcase }
end

#parse_file(resource, opts = {}) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
# File 'lib/iif/parser.rb', line 47

def parse_file(resource, opts = {})
  resource.each_line do |line|
    next if line.strip! == ""
    fields = parse_line(line, opts)
    if fields[0][0] == '!'
      parse_definition(fields)
    else
      parse_data(fields)
    end
  end
end

#parse_line(line, opts = {}) ⇒ Object



37
38
39
40
41
42
43
44
45
# File 'lib/iif/parser.rb', line 37

def parse_line(line, opts = {})
  ar = line.split(/\t/)
  if ar.size == 1
    ar = CSV.parse_line(line, opts).map { |i| i == nil ? "" : i }
  else
    ar.map! { |value| clean_field(value) }
  end
  ar
end