rock_books 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.rspec +3 -0
- data/.travis.yml +5 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +200 -0
- data/RELEASE_NOTES.md +4 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/rock_books +5 -0
- data/lib/rock_books/cmd_line/command_line_interface.rb +391 -0
- data/lib/rock_books/cmd_line/main.rb +108 -0
- data/lib/rock_books/documents/book_set.rb +113 -0
- data/lib/rock_books/documents/chart_of_accounts.rb +113 -0
- data/lib/rock_books/documents/journal.rb +161 -0
- data/lib/rock_books/documents/journal_entry.rb +73 -0
- data/lib/rock_books/documents/journal_entry_builder.rb +148 -0
- data/lib/rock_books/errors/account_not_found_error.rb +20 -0
- data/lib/rock_books/errors/error.rb +10 -0
- data/lib/rock_books/filters/acct_amount_filters.rb +12 -0
- data/lib/rock_books/filters/journal_entry_filters.rb +84 -0
- data/lib/rock_books/helpers/book_set_loader.rb +62 -0
- data/lib/rock_books/helpers/parse_helper.rb +22 -0
- data/lib/rock_books/reports/balance_sheet.rb +60 -0
- data/lib/rock_books/reports/income_statement.rb +63 -0
- data/lib/rock_books/reports/multidoc_transaction_report.rb +66 -0
- data/lib/rock_books/reports/receipts_report.rb +57 -0
- data/lib/rock_books/reports/report_context.rb +15 -0
- data/lib/rock_books/reports/reporter.rb +118 -0
- data/lib/rock_books/reports/transaction_report.rb +103 -0
- data/lib/rock_books/reports/tx_by_account.rb +82 -0
- data/lib/rock_books/reports/tx_one_account.rb +63 -0
- data/lib/rock_books/types/account.rb +7 -0
- data/lib/rock_books/types/account_type.rb +33 -0
- data/lib/rock_books/types/acct_amount.rb +52 -0
- data/lib/rock_books/version.rb +3 -0
- data/lib/rock_books.rb +7 -0
- data/rock_books.gemspec +39 -0
- data/sample_data/minimal/rockbooks-inputs/2017-xyz-chart-of-accounts.rbt +62 -0
- data/sample_data/minimal/rockbooks-inputs/2017-xyz-checking-journal.rbt +17 -0
- data/sample_data/minimal/rockbooks-inputs/2017-xyz-general-journal.rbt +14 -0
- data/sample_data/minimal/rockbooks-inputs/2017-xyz-visa-journal.rbt +23 -0
- metadata +158 -0
@@ -0,0 +1,118 @@
|
|
1
|
+
require_relative '../documents/journal_entry'
|
2
|
+
|
3
|
+
module RockBooks
|
4
|
+
module Reporter
|
5
|
+
|
6
|
+
module_function
|
7
|
+
|
8
|
+
SHORT_NAME_MAX_LENGTH = 16
|
9
|
+
|
10
|
+
SHORT_NAME_FORMAT_STRING = "%#{SHORT_NAME_MAX_LENGTH}.#{SHORT_NAME_MAX_LENGTH}s"
|
11
|
+
|
12
|
+
|
13
|
+
def page_width
|
14
|
+
context.page_width || 80
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
def format_account_code(code)
|
19
|
+
"%*.*s" % [max_account_code_length, max_account_code_length, code]
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
def account_code_name_type_string(account)
|
24
|
+
"#{account.code} -- #{account.name} (#{account.type.to_s.capitalize})"
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def format_amount(amount)
|
29
|
+
"%9.2f" % amount
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
# e.g. " 117.70 tr.mileage Travel - Mileage Allowance"
|
34
|
+
def format_acct_amount(acct_amount)
|
35
|
+
"%s %s %s" % [
|
36
|
+
format_amount(acct_amount.amount),
|
37
|
+
format_account_code(acct_amount.code),
|
38
|
+
context.chart_of_accounts.name_for_code(acct_amount.code)
|
39
|
+
]
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
def banner_line
|
44
|
+
@banner_line ||= '-' * page_width
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
def center(string)
|
49
|
+
indent = (page_width - string.length) / 2
|
50
|
+
indent = 0 if indent < 0
|
51
|
+
(' ' * indent) + string
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
def max_account_code_length
|
56
|
+
@max_account_code_length ||= context.chart_of_accounts.max_account_code_length
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
def generate_and_format_totals(section_caption, totals)
|
61
|
+
output = section_caption
|
62
|
+
output << "\n#{'-' * section_caption.length}\n\n"
|
63
|
+
format_string = "%12.2f %-#{context.chart_of_accounts.max_account_code_length}s %s\n"
|
64
|
+
totals.keys.sort.each do |account_code|
|
65
|
+
account_name = context.chart_of_accounts.name_for_code(account_code)
|
66
|
+
account_total = totals[account_code]
|
67
|
+
output << format_string % [account_total, account_code, account_name]
|
68
|
+
end
|
69
|
+
|
70
|
+
output << "------------\n"
|
71
|
+
output << "%12.2f\n" % totals.values.sum.round(2)
|
72
|
+
output
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
def generate_account_type_section(section_caption, totals, section_type, need_to_reverse_sign)
|
77
|
+
account_codes_this_section = context.chart_of_accounts.account_codes_of_type(section_type)
|
78
|
+
|
79
|
+
totals_this_section = totals.select do |account_code, _amount|
|
80
|
+
account_codes_this_section.include?(account_code)
|
81
|
+
end
|
82
|
+
|
83
|
+
if need_to_reverse_sign
|
84
|
+
totals_this_section.each { |code, amount| totals_this_section[code] = -amount }
|
85
|
+
end
|
86
|
+
|
87
|
+
section_total_amount = totals_this_section.map { |aa| aa.last }.sum
|
88
|
+
|
89
|
+
output = generate_and_format_totals(section_caption, totals_this_section)
|
90
|
+
[ output, section_total_amount ]
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
def format_multidoc_entry(entry)
|
95
|
+
acct_amounts = entry.acct_amounts
|
96
|
+
|
97
|
+
# "2017-10-29 hsbc_visa":
|
98
|
+
output = entry.date.to_s << ' ' << (SHORT_NAME_FORMAT_STRING % entry.doc_short_name)
|
99
|
+
|
100
|
+
indent = ' ' * output.length
|
101
|
+
|
102
|
+
output << format_acct_amount(acct_amounts.first) << "\n"
|
103
|
+
|
104
|
+
acct_amounts[1..-1].each do |acct_amount|
|
105
|
+
output << indent << format_acct_amount(acct_amount) << "\n"
|
106
|
+
end
|
107
|
+
|
108
|
+
if entry.description && entry.description.length > 0
|
109
|
+
output << entry.description
|
110
|
+
end
|
111
|
+
|
112
|
+
output
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require_relative 'reporter'
|
2
|
+
require_relative 'report_context'
|
3
|
+
|
4
|
+
module RockBooks
|
5
|
+
|
6
|
+
class TransactionReport
|
7
|
+
|
8
|
+
include Reporter
|
9
|
+
|
10
|
+
attr_accessor :journal, :context
|
11
|
+
|
12
|
+
|
13
|
+
def initialize(journal, report_context)
|
14
|
+
@journal = journal
|
15
|
+
@context = report_context
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
def generate_header
|
20
|
+
|
21
|
+
code = journal.account_code
|
22
|
+
name = journal.chart_of_accounts.name_for_code(code)
|
23
|
+
title = "Transactions for Account ##{code} -- #{name}"
|
24
|
+
|
25
|
+
lines = [banner_line]
|
26
|
+
lines << center(context.entity || 'Unspecified Entity')
|
27
|
+
lines << center(journal.title) if journal.title && journal.title.length > 0
|
28
|
+
lines << center(title)
|
29
|
+
lines << banner_line
|
30
|
+
lines << ''
|
31
|
+
lines << ''
|
32
|
+
lines << ''
|
33
|
+
lines.join("\n")
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def format_entry_first_acct_amount(entry)
|
38
|
+
entry.date.to_s \
|
39
|
+
<< ' ' \
|
40
|
+
<< format_acct_amount(entry.acct_amounts.first) \
|
41
|
+
<< "\n"
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
# Formats an entry like this, with entry description added on additional line(s) if it exists:
|
46
|
+
# 2018-05-21 $120.00 701 Office Supplies
|
47
|
+
def format_entry_no_split(entry)
|
48
|
+
output = format_entry_first_acct_amount(entry)
|
49
|
+
|
50
|
+
if entry.description && entry.description.length > 0
|
51
|
+
output << entry.description
|
52
|
+
end
|
53
|
+
output
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
# Formats an entry like this, with entry description added on additional line(s) if it exists::
|
58
|
+
# 2018-05-21 $120.00 95.00 701 Office Supplies
|
59
|
+
# 25.00 751 Gift to Customer
|
60
|
+
def format_entry_with_split(entry)
|
61
|
+
output = format_entry_first_acct_amount(entry)
|
62
|
+
indent = ' ' * 12
|
63
|
+
|
64
|
+
entry.acct_amounts[1..-1].each do |acct_amount|
|
65
|
+
output << indent << format_acct_amount(acct_amount) << "\n"
|
66
|
+
end
|
67
|
+
|
68
|
+
if entry.description && entry.description.length > 0
|
69
|
+
output << entry.description
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
def format_entry(entry)
|
75
|
+
if entry.acct_amounts.size > 2
|
76
|
+
format_entry_with_split(entry)
|
77
|
+
else
|
78
|
+
format_entry_no_split(entry)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
def generate_report(filter = nil)
|
84
|
+
sio = StringIO.new
|
85
|
+
sio << generate_header
|
86
|
+
|
87
|
+
entries = journal.entries
|
88
|
+
if filter
|
89
|
+
entries = entries.select { |entry| filter.(entry) }
|
90
|
+
end
|
91
|
+
|
92
|
+
entries.each { |entry| sio << format_entry(entry) << "\n" }
|
93
|
+
totals = AcctAmount.aggregate_amounts_by_account(JournalEntry.entries_acct_amounts(entries))
|
94
|
+
sio << generate_and_format_totals('Totals', totals)
|
95
|
+
sio.string
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
alias_method :to_s, :generate_report
|
100
|
+
alias_method :call, :generate_report
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require_relative '../documents/chart_of_accounts'
|
2
|
+
require_relative '../documents/journal'
|
3
|
+
require_relative 'reporter'
|
4
|
+
require_relative 'report_context'
|
5
|
+
|
6
|
+
module RockBooks
|
7
|
+
|
8
|
+
class TxByAccount
|
9
|
+
|
10
|
+
include Reporter
|
11
|
+
|
12
|
+
attr_accessor :context
|
13
|
+
|
14
|
+
|
15
|
+
def initialize(report_context)
|
16
|
+
@context = report_context
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
def generate_header
|
21
|
+
lines = [banner_line]
|
22
|
+
lines << center(context.entity || 'Unspecified Entity')
|
23
|
+
lines << center("Transactions by Account")
|
24
|
+
lines << banner_line
|
25
|
+
lines << ''
|
26
|
+
lines << ''
|
27
|
+
lines << ''
|
28
|
+
lines.join("\n")
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
def account_header(account, account_total)
|
33
|
+
total_string = "%.2f" % account_total
|
34
|
+
title = "Total: #{total_string} -- #{account_code_name_type_string(account)})"
|
35
|
+
|
36
|
+
<<~HEREDOC
|
37
|
+
#{banner_line}
|
38
|
+
#{center(title)}
|
39
|
+
#{banner_line}
|
40
|
+
|
41
|
+
HEREDOC
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
def account_total_line(account_code, account_total)
|
46
|
+
account_name = context.chart_of_accounts.name_for_code(account_code)
|
47
|
+
"%.2f Total for account: %s - %s" % [account_total, account_code, account_name]
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
def generate_report
|
52
|
+
output = generate_header
|
53
|
+
|
54
|
+
all_entries = Journal.entries_in_documents(context.journals)
|
55
|
+
|
56
|
+
context.chart_of_accounts.accounts.each do |account|
|
57
|
+
code = account.code
|
58
|
+
account_entries = JournalEntry.entries_containing_account_code(all_entries, code)
|
59
|
+
account_total = JournalEntry.total_for_code(account_entries, code)
|
60
|
+
output << account_header(account, account_total)
|
61
|
+
|
62
|
+
account_entries.each do |entry|
|
63
|
+
output << format_multidoc_entry(entry) << "\n"
|
64
|
+
output << "\n" if entry.description && entry.description.length > 0
|
65
|
+
end
|
66
|
+
output << account_total_line(code, account_total) << "\n"
|
67
|
+
output << "\n\n\n"
|
68
|
+
end
|
69
|
+
|
70
|
+
totals = AcctAmount.aggregate_amounts_by_account(JournalEntry.entries_acct_amounts(all_entries))
|
71
|
+
output << generate_and_format_totals('Totals', totals)
|
72
|
+
|
73
|
+
output
|
74
|
+
end
|
75
|
+
|
76
|
+
alias_method :to_s, :generate_report
|
77
|
+
alias_method :call, :generate_report
|
78
|
+
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require_relative '../documents/chart_of_accounts'
|
2
|
+
require_relative '../documents/journal'
|
3
|
+
require_relative 'reporter'
|
4
|
+
require_relative 'report_context'
|
5
|
+
|
6
|
+
module RockBooks
|
7
|
+
|
8
|
+
class TxOneAccount
|
9
|
+
|
10
|
+
include Reporter
|
11
|
+
|
12
|
+
attr_reader :context, :account_code, :account
|
13
|
+
|
14
|
+
|
15
|
+
def initialize(report_context, account_code)
|
16
|
+
@context = report_context
|
17
|
+
@account_code = account_code
|
18
|
+
@account = context.chart_of_accounts.account_for_code(account_code)
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def generate_header(account_total)
|
23
|
+
lines = [banner_line]
|
24
|
+
lines << center(context.entity || 'Unspecified Entity')
|
25
|
+
lines << center("Transactions for Account #{account_code_name_type_string(account)}")
|
26
|
+
lines << center("Total: %.2f" % account_total)
|
27
|
+
lines << banner_line
|
28
|
+
lines << ''
|
29
|
+
lines << ''
|
30
|
+
lines << ''
|
31
|
+
lines.join("\n")
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
def process_account(entries)
|
36
|
+
entries.each_with_object('') do |entry, output|
|
37
|
+
output << format_multidoc_entry(entry) << "\n"
|
38
|
+
output << "\n" if entry.description && entry.description.length > 0
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
def generate_report
|
44
|
+
entries = Journal.entries_in_documents(context.journals, JournalEntryFilters.account_code_filter(account_code))
|
45
|
+
account_total = JournalEntry.total_for_code(entries, account_code)
|
46
|
+
output = generate_header(account_total)
|
47
|
+
|
48
|
+
if entries.empty?
|
49
|
+
output << "There were no transactions for this account.\n\n\n\n"
|
50
|
+
else
|
51
|
+
output << process_account(entries)
|
52
|
+
totals = AcctAmount.aggregate_amounts_by_account(JournalEntry.entries_acct_amounts(entries))
|
53
|
+
output << generate_and_format_totals('Totals', totals)
|
54
|
+
end
|
55
|
+
|
56
|
+
output
|
57
|
+
end
|
58
|
+
|
59
|
+
alias_method :to_s, :generate_report
|
60
|
+
alias_method :call, :generate_report
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative '../errors/error'
|
2
|
+
|
3
|
+
module RockBooks
|
4
|
+
|
5
|
+
class AccountType < Struct.new(:symbol, :singular_name, :plural_name)
|
6
|
+
|
7
|
+
ASSET = self.new(:asset, 'Asset', 'Assets')
|
8
|
+
LIABILITY = self.new(:liability, 'Liability', 'Liabilities')
|
9
|
+
EQUITY = self.new(:equity, 'Equity', 'Equity')
|
10
|
+
INCOME = self.new(:income, 'Income', 'Income')
|
11
|
+
EXPENSE = self.new(:expense, 'Expense', 'Expenses')
|
12
|
+
|
13
|
+
ALL_TYPES = [ASSET, LIABILITY, EQUITY, INCOME, EXPENSE]
|
14
|
+
|
15
|
+
TYPE_HASH = {
|
16
|
+
'A' => ASSET,
|
17
|
+
'L' => LIABILITY,
|
18
|
+
'O' => EQUITY,
|
19
|
+
'I' => INCOME,
|
20
|
+
'E' => EXPENSE
|
21
|
+
}
|
22
|
+
|
23
|
+
# Converts strings
|
24
|
+
def self.to_type(string)
|
25
|
+
type = TYPE_HASH[string[0].upcase]
|
26
|
+
if type.nil?
|
27
|
+
raise Error.new("Account type of #{string} not valid. " +
|
28
|
+
"Must be one of #{TYPE_HASH.keys} (#{ALL_TYPES.map(&:singular_name)})")
|
29
|
+
end
|
30
|
+
type
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module RockBooks
|
2
|
+
|
3
|
+
# This class represents an account code and an amount.
|
4
|
+
# Journal entries will have multiple instances of these.
|
5
|
+
class AcctAmount < Struct.new(:date, :code, :amount)
|
6
|
+
|
7
|
+
|
8
|
+
# Same as constructor except it raises an error if the account code is not in the chart of accounts.
|
9
|
+
def self.create_with_chart_validation(date, code, amount, chart_of_accounts)
|
10
|
+
unless chart_of_accounts.include?(code)
|
11
|
+
raise AccountNotFoundError.new(code)
|
12
|
+
end
|
13
|
+
self.new(date, code, amount)
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
def self.total_amount(acct_amounts)
|
18
|
+
acct_amounts.inject(0) { |sum, acct_amount| sum += acct_amount.amount }
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
# Returns a hash whose keys are account codes and values are the totals for those codes.
|
23
|
+
# The 'aggregate' in the method name is intended to be a noun, not a verb.
|
24
|
+
def self.aggregate_amounts_by_account(acct_amounts)
|
25
|
+
totals = acct_amounts.each_with_object(Hash.new(0)) do |acct_amount, by_account|
|
26
|
+
by_account[acct_amount.code] += acct_amount.amount
|
27
|
+
end
|
28
|
+
totals.each do |code, amount |
|
29
|
+
totals[code] = amount.round(2)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
# Returns the subset of the passed array of acct_amount's that contain the specified account code
|
35
|
+
def self.containing_code(acct_amounts, account_code)
|
36
|
+
acct_amounts.select { |acct_amount| acct_amount.code == account_code }
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
# For the passed array of AcctAmount's, calculate the total for a single account.
|
41
|
+
def self.total_amount_for_code(acct_amounts, account_code)
|
42
|
+
containing_code(acct_amounts, account_code) \
|
43
|
+
.map(&:amount) \
|
44
|
+
.sum
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
def self.filter(acct_amounts, filter)
|
49
|
+
acct_amounts.select { |acct_amount| filter.(acct_amount)}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/rock_books.rb
ADDED
data/rock_books.gemspec
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "rock_books/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "rock_books"
|
8
|
+
spec.version = RockBooks::VERSION
|
9
|
+
spec.authors = ["Keith Bennett"]
|
10
|
+
spec.email = ["keithrbennett@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Very basic accounting package.}
|
13
|
+
spec.description = %q{Extremely primitive accounting software.}
|
14
|
+
spec.homepage = "http://example.com"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
18
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
19
|
+
# if spec.respond_to?(:metadata)
|
20
|
+
# spec.metadata["allowed_push_host"] = ": Set to 'http://mygemserver.com'"
|
21
|
+
# else
|
22
|
+
# raise "RubyGems 2.0 or newer is required to protect against " \
|
23
|
+
# "public gem pushes."
|
24
|
+
# end
|
25
|
+
|
26
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
27
|
+
f.match(%r{^(test|spec|features)/})
|
28
|
+
end
|
29
|
+
spec.bindir = "exe"
|
30
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
31
|
+
spec.require_paths = ["lib"]
|
32
|
+
|
33
|
+
spec.add_dependency 'awesome_print', '> 0'
|
34
|
+
spec.add_dependency 'pry', '> 0.0.0'
|
35
|
+
|
36
|
+
spec.add_development_dependency "bundler", "~> 1.16"
|
37
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
38
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
39
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
@doc_type: chart_of_accounts
|
2
|
+
@title: Chart of Accounts - 2017
|
3
|
+
@entity: XYZ Consulting, Inc.
|
4
|
+
|
5
|
+
|
6
|
+
# Assets
|
7
|
+
|
8
|
+
ck.hsbc A HSBC Checking
|
9
|
+
paypal A Paypal
|
10
|
+
accts.rec A Accounts Receivable
|
11
|
+
|
12
|
+
|
13
|
+
# Liabilities
|
14
|
+
|
15
|
+
cc.hsbc.visa L Visa Credit Card
|
16
|
+
loan.to.sh L Loan Payable to Shareholder
|
17
|
+
|
18
|
+
|
19
|
+
# Equity
|
20
|
+
|
21
|
+
own.equity O Owner's Equity
|
22
|
+
ret.earn O Retained Earnings
|
23
|
+
|
24
|
+
|
25
|
+
# Income
|
26
|
+
|
27
|
+
sls.cons I Sales - Consulting
|
28
|
+
|
29
|
+
|
30
|
+
# Expenses
|
31
|
+
|
32
|
+
bank.fees E Bank Charges
|
33
|
+
books.refs E Books, Screencasts, References
|
34
|
+
conf.fees E Conference Fees
|
35
|
+
cowork.fees E Coworking Fees
|
36
|
+
govt.fees E Government Fees
|
37
|
+
inet.fees E Internet Service, Domain, and Hosting Fees
|
38
|
+
insurance E Insurance
|
39
|
+
int.exp E Interest Expense
|
40
|
+
mktng.exp E Marketing Expenses
|
41
|
+
meals.ent E Meals & Entertainment
|
42
|
+
misc.exp E Miscellaneous Expenses
|
43
|
+
prof.fees E Professional Fees
|
44
|
+
repair.maint E Repair & Maintenance
|
45
|
+
ship.exp E Shipping and Mailing Expenses
|
46
|
+
sw.exp E Software Expense
|
47
|
+
supplies E Supplies
|
48
|
+
cc.proc E Credit Card Processing Fees
|
49
|
+
tr.airfare E Travel - Air Fares
|
50
|
+
tr.autorent E Travel - Auto Rental
|
51
|
+
tr.gas.etc E Travel - Gas, Oil, Tolls, etc.
|
52
|
+
tr.govt E Travel - Government Fees
|
53
|
+
tr.lodging E Travel - Lodging
|
54
|
+
tr.m.i E Travel - Meals & Incidentals
|
55
|
+
tr.mileage E Travel - Mileage Allowance
|
56
|
+
tr.misc E Travel - Miscellaneous
|
57
|
+
tr.parking E Travel - Parking
|
58
|
+
tr.perdiem.mi E Travel - Per Diem (Meals and Incidentals)
|
59
|
+
tr.taxi E Travel - Taxi
|
60
|
+
tr.trainfare E Travel - Train Fare
|
61
|
+
tr.m.e E Meals and Entertainment
|
62
|
+
tr.unclass E Expenses Not Yet Classified
|
@@ -0,0 +1,17 @@
|
|
1
|
+
@doc_type: journal
|
2
|
+
@title: HSBC Checking Disbursements Journal - 2017
|
3
|
+
@account_code: ck.hsbc
|
4
|
+
@debit_or_credit: debit
|
5
|
+
@short_name: ck.hsbc
|
6
|
+
@date_prefix: 2017-
|
7
|
+
|
8
|
+
01-01 -5000.00 own.equity
|
9
|
+
Initial Deposit from Shareholder
|
10
|
+
|
11
|
+
01-05 2000.00 cc.hsbc.visa
|
12
|
+
|
13
|
+
01-07 -10000.00 sls.cons
|
14
|
+
Invoice #437, Dec. 2016 work, ABC, Inc.
|
15
|
+
|
16
|
+
|
17
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
@doc_type: general_journal
|
2
|
+
@title: General Journal - 2017
|
3
|
+
@date_prefix: 2017-
|
4
|
+
@short_name: general
|
5
|
+
|
6
|
+
01-08 tr.airfare 300.00 loan.to.sh -300.00
|
7
|
+
Phoenix conference air ticket paid on personal credit card
|
8
|
+
|
9
|
+
01-20 tr.perdiem.mi 495.00 loan.to.sh -495.00
|
10
|
+
Per diem allowance for Phoenix conference (see worksheet)
|
11
|
+
|
12
|
+
01-31 tr.mileage 117.70 loan.to.sh -117.70
|
13
|
+
Mileage reimbursement for business travel of January 2017 (see worksheet)
|
14
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
@doc_type: journal
|
2
|
+
@title: HSBC Visa Journal - 2017
|
3
|
+
@account_code: cc.hsbc.visa
|
4
|
+
@short_name: hsbc_visa
|
5
|
+
@debit_or_credit: debit
|
6
|
+
@date_prefix: 2017-
|
7
|
+
|
8
|
+
01-02 750 insurance
|
9
|
+
Professional insurance for the year 2017, Hartford Insurance
|
10
|
+
Receipt: 01/2017-01-02-hartford-insurance.pdf
|
11
|
+
|
12
|
+
01-02 100 cowork.fees
|
13
|
+
New Work City coworking fee for the month of January
|
14
|
+
Receipt: 01/2017-01-02-nwc.pdf
|
15
|
+
|
16
|
+
01-06 500 conf.fees
|
17
|
+
Phoenix conference registration fee
|
18
|
+
Receipt: 01/2017-01-06-phoenix-conference-registration.pdf
|
19
|
+
|
20
|
+
01-20 400 tr.lodging
|
21
|
+
Hampton Inn Phoenix (conference)
|
22
|
+
Receipt: 01/2017-01-20-phoenix-hampton.pdf
|
23
|
+
|