88 lines
2.4 KiB
Ruby

require "zlib"
require "nokogiri"
module Gnucash
# Represent a GnuCash Book
class Book
# _Array_ of _Gnucash::Account_ objects in the book
attr_accessor :accounts
# _Array_ of _Gnucash::Transaction_ objects in the book
attr_accessor :transactions
# _String_ in "YYYY-MM-DD" format of the first transaction in the book
attr_accessor :start_date
# _String_ in "YYYY-MM-DD" format of the last transaction in the book
attr_accessor :end_date
# Construct a Book object.
# Normally called internally by Gnucash.open()
# === Arguments
# +fname+ _String_:: The file name of the GnuCash file to open.
def initialize(fname)
begin
@ng = Nokogiri.XML(Zlib::GzipReader.open(fname).read)
rescue Zlib::GzipFile::Error
@ng = Nokogiri.XML(File.read(fname))
end
book_nodes = @ng.xpath('/gnc-v2/gnc:book')
if book_nodes.count != 1
raise "Error: Expected to find one gnc:book entry"
end
@book_node = book_nodes.first
build_accounts
build_transactions
finalize
end
# Return a handle to the Account object that has the given GUID.
# === Arguments
# +id+ _String_:: GUID
# === Return
# _Gnucash::Account_ or +nil+
def find_account_by_id(id)
@accounts.find { |a| a.id == id }
end
# Return a handle to the Account object that has the given fully-qualified
# name.
# === Arguments
# +full_name+ _String_::
# Fully-qualified account name (ex: "Expenses::Auto::Gas")
# === Return
# _Gnucash::Account_ or +nil+
def find_account_by_full_name(full_name)
@accounts.find { |a| a.full_name == full_name }
end
private
def build_accounts
@accounts = @book_node.xpath('gnc:account').map do |act_node|
Account.new(self, act_node)
end
end
def build_transactions
@start_date = nil
@end_date = nil
@transactions = @book_node.xpath('gnc:transaction').map do |txn_node|
Transaction.new(self, txn_node).tap do |txn|
@start_date = txn.date if @start_date.nil? or txn.date < @start_date
@end_date = txn.date if @end_date.nil? or txn.date > @end_date
end
end
end
def finalize
@accounts.sort! do |a, b|
a.full_name <=> b.full_name
end
@accounts.each do |account|
account.finalize
end
end
end
end