Class: RockBooks::JournalEntryBuilder
- Inherits:
-
Struct
- Object
- Struct
- RockBooks::JournalEntryBuilder
- Defined in:
- lib/rock_books/documents/journal_entry_builder.rb
Instance Attribute Summary collapse
-
#journal_entry_context ⇒ Object
Returns the value of attribute journal_entry_context.
Instance Method Summary collapse
-
#acct_amounts_from_tokens(tokens, date) ⇒ Object
A “token” in this context means an account name and account amount pair, e.g.
- #build ⇒ Object
-
#build_acct_amount_array(date, tokens) ⇒ Object
Returns an array of AcctAmount instances for the array of tokens.
- #chart_of_accounts ⇒ Object
- #convert_amounts_to_floats(tokens) ⇒ Object
-
#convert_signs_for_debit_credit(tokens) ⇒ Object
For regular journal only, not general journal.
- #general_journal? ⇒ Boolean
- #journal ⇒ Object
- #line ⇒ Object
- #linenum ⇒ Object
- #validate_acct_amount_token_array_size(tokens) ⇒ Object
- #validate_transaction_is_balanced(acct_amounts) ⇒ Object
Instance Attribute Details
#journal_entry_context ⇒ Object
Returns the value of attribute 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
A “token” in this context means an account name and account amount pair, e.g. “pnc.checking 1234.56”.
21 22 23 24 25 26 27 28 29 |
# File 'lib/rock_books/documents/journal_entry_builder.rb', line 21 def acct_amounts_from_tokens(tokens, date) acct_amounts = [] tokens[0..-1].each_slice(2).each do |(account_code, amount)| acct_amounts << AcctAmount.create_with_chart_validation(date, account_code, amount, journal_entry_context) end acct_amounts end |
#build ⇒ Object
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/rock_books/documents/journal_entry_builder.rb', line 138 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.
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 124 125 126 127 |
# File 'lib/rock_books/documents/journal_entry_builder.rb', line 91 def build_acct_amount_array(date, tokens) unless general_journal? if journal.account_code.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.account_code) # 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_accounts ⇒ Object
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
39 40 41 42 43 |
# File 'lib/rock_books/documents/journal_entry_builder.rb', line 39 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.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/rock_books/documents/journal_entry_builder.rb', line 53 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. adjust_sign_for_main_account = ->(amount) do (journal.debit_or_credit == :debit) ? -amount : amount end adjust_sign_for_other_accounts = ->(amount) do - adjust_sign_for_main_account.(amount) end tokens[1] = adjust_sign_for_main_account.(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
46 47 48 |
# File 'lib/rock_books/documents/journal_entry_builder.rb', line 46 def general_journal? journal.doc_type == 'general_journal' end |
#journal ⇒ Object
11 |
# File 'lib/rock_books/documents/journal_entry_builder.rb', line 11 def journal; journal_entry_context.journal; end |
#line ⇒ Object
13 |
# File 'lib/rock_books/documents/journal_entry_builder.rb', line 13 def line; journal_entry_context.line; end |
#linenum ⇒ Object
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
32 33 34 35 36 |
# File 'lib/rock_books/documents/journal_entry_builder.rb', line 32 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
130 131 132 133 134 135 |
# File 'lib/rock_books/documents/journal_entry_builder.rb', line 130 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 |