class RockBooks::Journal

The journal will create journal entries, each of which containing an array of account/amount objects, copying the entry date to them.

Warning: Any line beginning with a number will be assumed to be the date of a data line for an entry, so descriptions cannot begin with a number.

Attributes

account_code[R]
chart_of_accounts[R]
date_prefix[R]
debit_or_credit[R]
doc_type[R]
entries[R]
short_name[R]
title[R]

Public Class Methods

acct_amounts_in_documents(documents, entries_filter = nil, acct_amounts_filter = nil) click to toggle source
# File lib/rock_books/documents/journal.rb, line 48
def self.acct_amounts_in_documents(documents, entries_filter = nil, acct_amounts_filter = nil)
  entries = entries_in_documents(documents, entries_filter)

  acct_amounts = entries.each_with_object([]) do |entry, acct_amounts|
    acct_amounts << entry.acct_amounts
  end.flatten

  if acct_amounts_filter
    acct_amounts = AcctAmount.filter(acct_amounts, filter)
  end

  acct_amounts
end
entries_in_documents(documents, filter = nil) click to toggle source

Returns the entries in the specified documents, sorted by date and document short name, optionally filtered with the specified filter.

# File lib/rock_books/documents/journal.rb, line 33
def self.entries_in_documents(documents, filter = nil)
  entries = documents.each_with_object([]) do |document, entries|
    entries << document.entries
  end.flatten

  if filter
    entries = entries.select {|entry| filter.(entry) }
  end

  entries.sort_by do |entry|
    [entry.date, entry.doc_short_name]
  end
end
from_file(chart_of_accounts, file) click to toggle source
# File lib/rock_books/documents/journal.rb, line 21
def self.from_file(chart_of_accounts, file)
  self.new(chart_of_accounts, File.readlines(file).map(&:chomp))
end
from_string(chart_of_accounts, string) click to toggle source
# File lib/rock_books/documents/journal.rb, line 26
def self.from_string(chart_of_accounts, string)
  self.new(chart_of_accounts, string.split("\n"))
end
new(chart_of_accounts, input_lines) click to toggle source

short_name is a name that will appear on reports identifying the journal from which a transaction comes

# File lib/rock_books/documents/journal.rb, line 68
def initialize(chart_of_accounts, input_lines)
  @chart_of_accounts = chart_of_accounts
  @entries = []
  @date_prefix = ''
  input_lines.each_with_index do |line, linenum|
    context = JournalEntryContext.new(self, linenum + 1, line)
    parse_line(context)
  end
end

Public Instance Methods

==(other) click to toggle source
# File lib/rock_books/documents/journal.rb, line 171
def ==(other)
  # excluding date_prefix from this test intentionally because it does not
  # affect the parsed data.
  short_name        == other.short_name          && \
  account_code      == other.account_code        && \
  chart_of_accounts == other.chart_of_accounts   && \
  debit_or_credit   == other.debit_or_credit     && \
  doc_type          == other.doc_type            && \
  title             == other.title               && \
  entries           == other.entries
end
acct_amounts() click to toggle source
# File lib/rock_books/documents/journal.rb, line 130
def acct_amounts
  entries.each_with_object([]) { |entry, acct_amounts|  acct_amounts << entry.acct_amounts }.flatten
end
parse_line(journal_entry_context) click to toggle source
# File lib/rock_books/documents/journal.rb, line 79
def parse_line(journal_entry_context)
  begin
    line = journal_entry_context.line
    case line.strip
    when /^@doc_type:/
      @doc_type = line.split(/^@doc_type:/).last.strip
    when  /^@account_code:/
      @account_code = line.split(/^@account_code:/).last.strip

      unless chart_of_accounts.include?(@account_code)
        raise AccountNotFoundError.new(@account_code, journal_entry_context)
      end

      # if debit or credit has not yet been specified, inherit the setting from the account:
      unless @debit_or_credit
        @debit_or_credit = chart_of_accounts.debit_or_credit_for_code(@account_code)
      end

    when /^@title:/
      @title = line.split(/^@title:/).last.strip
    when /^@short_name:/
      @short_name = line.split(/^@short_name:/).last.strip
    when /^@date_prefix:/
      @date_prefix = line.split(/^@date_prefix:/).last.strip
    when /^@debit_or_credit:/
      data = line.split(/^@debit_or_credit:/).last.strip
      @debit_or_credit = data.to_sym
    when /^$/
      # ignore empty line
    when /^#/
      # ignore comment line
    when /^\d/  # a date/acct/amount line starting with a number
      entries << JournalEntryBuilder.new(journal_entry_context).build
    else # Text line(s) to be attached to the most recently parsed transaction
      unless entries.last
        raise Error.new("Entry for this description cannot be found: #{line}")
      end
      entries.last.description << line << "\n"

      if /^Receipt:/.match(line)
        receipt_spec = line.split(/^Receipt:/).last.strip
        entries.last.receipts << receipt_spec
      end
    end
  rescue => e
    puts "Error occurred parsing:\n#{journal_entry_context}\n\n"
    raise
  end
end
to_h() click to toggle source
# File lib/rock_books/documents/journal.rb, line 155
def to_h
  {
      title:           title,
      account_code:    account_code,
      debit_or_credit: debit_or_credit,
      doc_type:        doc_type,
      date_prefix:     date_prefix,
      entries:         entries
  }
end
to_json() click to toggle source
# File lib/rock_books/documents/journal.rb, line 167
def to_json; to_h.to_json; end
to_s() click to toggle source
Calls superclass method
# File lib/rock_books/documents/journal.rb, line 145
def to_s
  super.to_s + ': ' + \
  {
      account_code: account_code,
      debit_or_credit: debit_or_credit,
      title: title
  }.to_s
end
to_yaml() click to toggle source
# File lib/rock_books/documents/journal.rb, line 168
def to_yaml; to_h.to_yaml; end
total_amount() click to toggle source
# File lib/rock_books/documents/journal.rb, line 140
def total_amount
  AcctAmount.total_amount(acct_amounts)
end
totals_by_account() click to toggle source
# File lib/rock_books/documents/journal.rb, line 135
def totals_by_account
  acct_amounts.each_with_object(Hash.new(0)) { |aa, totals| totals[aa.code] += aa.amount }
end