class Treasurer

Some thoughts on double entry accounting:

assets - liabilities = equity where equity = equity_at_start + income - expenses

so

assets - liabilities = equity_at_start + income - expenses

or alternatively

assets + expenses = equity_at_start + income + liabilities (1)

Good things:

Positive equity_at_start, positive assets, positive income, negative liabilities, negative expenses

A debit on the left of (1) must be matched by a credit on the right of (1) and vice versa.

A debit to an asset account increases the value of the asset. This means buying some land or supplies or depositing some cash in a bank account. You can think of it as a debit because you are locking up your equity in a way that may not be realisable. A credit to the asset account means drawing down on the asset, for example selling a bit of land or taking money out of a bank account.

Similarly, a debit to an expense account, effectively, spending money on that expense, increases the value of that account. Debits here are clearly negative things from the point of view of your wealth! (Credits to expense accounts would be something like travel reimbursements).

A credit to income increases the value of the income account… this seems obvious. If you credit income you must debit assets (you have to put your income somewhere, for example a bank account, i.e. you must effectively spend it by buying an asset: remember a bank may fail… a bank account is an asset with risk just as much as a painting).

A credit to liabilities increases the value of the liability, for example taking out a loan. Once you credit a liability you have to either buy (debit) an asset, or buy (debit) an expense directly (for example a loan to pay some fees).

In any accounting period, the sum of all debits and credits should be 0. Also, at the end of the accounting period,

equity_at_end = assets - liabilities = equity_at_start + income - expenses

This seems obvious to me!!

Constants

SCRIPT_FOLDER

Public Class Methods

add_file(file, account, copts={}) click to toggle source
# File lib/treasurer/commands.rb, line 4
def add_file(file, account, copts={})
        load_treasurer_folder(copts)
        ep 'entries', Dir.entries
        CodeRunner.submit(p: "{data_file: '#{File.expand_path(file)}', account: :#{account}}")
end
add_folder_of_files(folder, copts={}) click to toggle source
# File lib/treasurer/commands.rb, line 9
def add_folder_of_files(folder, copts={})
        #Dir.chdir(folder) do
                files = Dir.entries(folder).grep(/\.csv$/)
                accounts = files.map{|f| f.sub(/\.csv/, '')}
                files = files.map{|f| folder + '/' + f}
                p ['files789', files, accounts]
                files.zip(accounts).each{|f,a| add_file(f, a, copts)}
        #end
end
assign(copts={}) click to toggle source
# File lib/treasurer/commands.rb, line 32
def assign(copts={})
  load_treasurer_folder(copts)
  crcopts = eval(copts[:C]||"{}")
  #crcopts[:h] = nil
  #CodeRunner.run_command('generate_component_runs', crcopts)
  crcopts[:h] = :component
  crcopts[:O] = 'date'
  crcopts[:f] = 'not (component_runs and component_runs.size > 0 and component_runs[0].instance_variable_get(:@external_account))'
  crcopts[:f] = 'not (@external_account and @sub_account)'
  catch (:quit_data_entry) do
    CodeRunner.run_command('external_account', crcopts)
  end
end
check_is_treasurer_folder() click to toggle source
# File lib/treasurer/commands.rb, line 18
def check_is_treasurer_folder
        raise "This folder has not been set up to use with Treasurer; please initialise a folder with treasurer init" unless FileTest.exist? '.code_runner_script_defaults.rb' and eval(File.read('.code_runner_script_defaults.rb'))[:code] == 'budget'
end
create_report(copts = {}) click to toggle source
# File lib/treasurer/commands.rb, line 21
def create_report(copts = {})
        reporter = fetch_reporter(copts)
        reporter.report()
end
fetch_reporter(copts = {}) click to toggle source
# File lib/treasurer/commands.rb, line 25
  def fetch_reporter(copts = {})
          load_treasurer_folder(copts)
          Reporter.new(
CodeRunner.fetch_runner(h: :component),
days_before: copts[:b]||360, days_ahead: copts[:a]||180,
today: copts[:t], report_currency: copts[:r])
  end
init_root_folder(folder, copts={}) click to toggle source
# File lib/treasurer/commands.rb, line 49
    def init_root_folder(folder, copts={})
            raise "Folder already exists" if FileTest.exist? folder
            FileUtils.makedirs(folder)
            FileUtils.cp(
  SCRIPT_FOLDER + '/treasurer/local_customisations.rb',
  folder + '/local_customisations.rb')
            CodeRunner.fetch_runner(Y: folder, C: 'budget', X: '/dev/null')
init_sqlite(folder)
            eputs "\n\n Your treasurer folder '#{folder}' has been set up. All further treasurer commands should be run from within this folder.\n"
    end
init_sqlite(folder) click to toggle source
# File lib/treasurer/commands.rb, line 59
def init_sqlite(folder)
  CodeRunner::Budget.init_sqlite(folder)
end
list_last_updated(copts={}) click to toggle source
# File lib/treasurer/commands.rb, line 73
def list_last_updated(copts={})
  reporter = fetch_reporter(copts)
  reporter.generate_accounts
  accts = reporter.accounts.find_all{|ac| not ac.external and not ac.type==:Equity}
  puts "Account | Date "
  accts.each do |ac|
    #puts ac.name
    puts "#{ac.name} | #{ac.runs.sort_by{|r| r.date}[-1].date.to_s}"
  end
end
load_treasurer_folder(copts={}) click to toggle source
# File lib/treasurer/commands.rb, line 62
    def load_treasurer_folder(copts={})
            check_is_treasurer_folder
            Treasurer.send(:remove_const, :LocalCustomisations) if defined? Treasurer::LocalCustomisations
load 'local_customisations.rb'
            Treasurer::Reporter.send(:include, Treasurer::LocalCustomisations)
            Treasurer::Reporter::Account.send(:include, Treasurer::LocalCustomisations)
            Treasurer::Reporter::Analysis.send(:include, Treasurer::LocalCustomisations)
require 'budgetcrmod'
            CodeRunner::Budget.send(:include, Treasurer::LocalCustomisations)
            _runner = CodeRunner.fetch_runner(eval(copts[:C]||"{}"))
    end
method_missing(meth, *args) click to toggle source
# File lib/treasurer/commands.rb, line 84
def method_missing(meth, *args)
        CodeRunner.send(meth, *args)
end
setup(copts) click to toggle source

This function gets called before every command and allows arbitrary manipulation of the command options (copts) hash

# File lib/treasurer.rb, line 98
def setup(copts)
  # None neededed
  #copts[:b] = copts[:b].to_i if copts[:b]
  #copts[:a] = copts[:a].to_i if copts[:a]
  copts[:t] = Date.parse(copts[:t]) if copts[:t]
end
status(copts={}) click to toggle source
# File lib/treasurer/commands.rb, line 45
def status(copts={})
  load_treasurer_folder(copts)
  CodeRunner.status(eval(copts[:C]||"{}"))
end
verbosity() click to toggle source
# File lib/treasurer.rb, line 104
def verbosity
  2
end