rock_books 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|