Class: RockBooks::JournalEntryBuilder

Inherits:
Struct
  • Object
show all
Defined in:
lib/rock_books/documents/journal_entry_builder.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#journal_entry_contextObject

Returns the value of attribute journal_entry_context

Returns:

  • (Object)

    the current value of journal_entry_context



9
10
11
# File 'lib/rock_books/documents/journal_entry_builder.rb', line 9

def journal_entry_context
  @journal_entry_context
end

Instance Method Details

#acct_amounts_from_tokens(tokens, date) ⇒ Object



17
18
19
20
21
22
23
24
25
# File 'lib/rock_books/documents/journal_entry_builder.rb', line 17

def acct_amounts_from_tokens(tokens, date)
  acct_amounts = []

  tokens[0..-1].each_slice(2).each do |(, amount)|
    acct_amounts <<  AcctAmount.create_with_chart_validation(date, , amount, journal_entry_context)
  end

  acct_amounts
end

#buildObject



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/rock_books/documents/journal_entry_builder.rb', line 134

def build
  # this is an account line in the form: yyyy-mm-dd 101 blah blah blah
  tokens = line.split
  acct_amount_tokens = tokens[1..-1]
  date_string = journal.date_prefix + tokens[0]

  raise_date_format_error = -> do
    raise Error.new("Date string was '#{date_string}' but should be a valid date in the form YYYY-MM-DD in " + \
        "journal '#{journal_entry_context[:journal].title}', line #{journal_entry_context[:linenum]}.")
  end

  raise_date_format_error.() if date_string.length != 10

  begin
    date = Date.iso8601(date_string)
  rescue ArgumentError
    raise_date_format_error.()
  end

  unless chart_of_accounts.included_in_period?(date)
    raise DateRangeError.new(date, chart_of_accounts.start_date,
        chart_of_accounts.end_date, journal_entry_context)
  end

  acct_amounts = build_acct_amount_array(date, acct_amount_tokens)
  validate_transaction_is_balanced(acct_amounts)
  JournalEntry.new(date, acct_amounts, journal.short_name)
end

#build_acct_amount_array(date, tokens) ⇒ Object

Returns an array of AcctAmount instances for the array of tokens.

The following applies only to regular (not general) journals:

this token array will start with the transaction’s total amount and be followed by account/amount pairs.

Examples, assuming a line: 2018-05-20 5.79 701 1.23 702 4.56

and the journal account is ‘101’, ‘D’ ‘My Checking Account’, the following AcctAmoutns will be created:

AcctAmount code: ‘101’, amount: -5.79, AcctAmount code: ‘701’, 1.23, AcctAmount code: ‘702’, 4.56,

shortcut: if there is only 1 account (that is, it is not a split entry), give it the total amount

‘5.79’, ‘701’

–> [AcctAmount code: ‘101’, amount: -5.79, AcctAmount code: ‘701’, 5.79]

If the account is a credit account, the signs will be reversed.



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/rock_books/documents/journal_entry_builder.rb', line 87

def build_acct_amount_array(date, tokens)

  unless general_journal?
    if journal..nil?
      raise Error.new("An '@account_code: ' line has not yet been specified in this journal." )
    end

    # Prepend the array with the document account code so that total amount will be associated with it.
    tokens.unshift(journal.)

    # For convenience in regular journals, when there is no split,
    # we permit the user to omit the amount after the
    # account code, since we know it will be equal to the total amount.
    # We add it here, because we *will* need to include it in the data.
    if tokens.size == 3
      tokens << tokens[1]  # copy the total amount to the sole account's amount
    end
  end

  validate_acct_amount_token_array_size(tokens)

  # Tokens in the odd numbered positions are dollar amounts that need to be converted from string to float.
  begin
    convert_amounts_to_floats(tokens)
  rescue ArgumentError
    raise Error.new("Float conversion or other parse error for #{date}, #{tokens}.")
  end

  unless general_journal?
    # As a convenience, all normal journal amounts are entered as positive numbers.
    # This code negates the amounts as necessary so that debits are + and credits are -.
    # In general journals, the debit and credit amounts must be entered correctly already.
    convert_signs_for_debit_credit(tokens)
  end

  acct_amounts_from_tokens(tokens, date)
end

#chart_of_accountsObject



14
# File 'lib/rock_books/documents/journal_entry_builder.rb', line 14

def chart_of_accounts; journal_entry_context.chart_of_accounts;  end

#convert_amounts_to_floats(tokens) ⇒ Object



35
36
37
38
39
# File 'lib/rock_books/documents/journal_entry_builder.rb', line 35

def convert_amounts_to_floats(tokens)
  (1...tokens.size).step(2) do |amount_index|
    tokens[amount_index] = Float(tokens[amount_index])
  end
end

#convert_signs_for_debit_credit(tokens) ⇒ Object

For regular journal only, not general journal. This converts the entered signs to the correct debit/credit signs.



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/rock_books/documents/journal_entry_builder.rb', line 49

def convert_signs_for_debit_credit(tokens)

  # Adjust the sign of the amount for the main journal account (e.g. the checking account or credit card account)
  # e.g. If it's a checking account, it is an asset, a debit account, and the transaction total
  # will represent a credit to that checking account.
   = ->(amount) do
    (journal.debit_or_credit == :debit) ? -amount : amount
  end

  adjust_sign_for_other_accounts = ->(amount) do
    - .(amount)
  end

  tokens[1] = .(tokens[1])
  (3...tokens.size).step(2) do |amount_index|
    tokens[amount_index] = adjust_sign_for_other_accounts.(tokens[amount_index])
  end
end

#general_journal?Boolean

Returns:

  • (Boolean)


42
43
44
# File 'lib/rock_books/documents/journal_entry_builder.rb', line 42

def general_journal?
  journal.doc_type == 'general_journal'
end

#journalObject



11
# File 'lib/rock_books/documents/journal_entry_builder.rb', line 11

def journal;           journal_entry_context.journal;            end

#lineObject



13
# File 'lib/rock_books/documents/journal_entry_builder.rb', line 13

def line;              journal_entry_context.line;               end

#linenumObject



12
# File 'lib/rock_books/documents/journal_entry_builder.rb', line 12

def linenum;           journal_entry_context.linenum;            end

#validate_acct_amount_token_array_size(tokens) ⇒ Object



28
29
30
31
32
# File 'lib/rock_books/documents/journal_entry_builder.rb', line 28

def validate_acct_amount_token_array_size(tokens)
  if tokens.size.odd?
    raise IncorrectSequenceError.new(tokens, journal_entry_context)
  end
end

#validate_transaction_is_balanced(acct_amounts) ⇒ Object



126
127
128
129
130
131
# File 'lib/rock_books/documents/journal_entry_builder.rb', line 126

def validate_transaction_is_balanced(acct_amounts)
  sum = acct_amounts.map(&:amount).sum.round(4)
  unless sum == 0.0
    raise TransactionNotBalancedError.new(sum, journal_entry_context)
  end
end