vfwcash 0.3.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.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +107 -0
  6. data/Rakefile +2 -0
  7. data/bin/vfwcash +5 -0
  8. data/lib/models/audit.rb +228 -0
  9. data/lib/models/balance.rb +95 -0
  10. data/lib/models/between.rb +100 -0
  11. data/lib/models/cash_account.rb +69 -0
  12. data/lib/models/gcash.rb +189 -0
  13. data/lib/models/ledger.rb +109 -0
  14. data/lib/models/register.rb +54 -0
  15. data/lib/models/split.rb +26 -0
  16. data/lib/models/split_ledger.rb +69 -0
  17. data/lib/models/sqlite_base.rb +10 -0
  18. data/lib/models/summary.rb +98 -0
  19. data/lib/models/tran.rb +12 -0
  20. data/lib/templates/vfw-gray.png +0 -0
  21. data/lib/templates/vfwcash.gnucash +0 -0
  22. data/lib/templates/vfwcash.yml +95 -0
  23. data/lib/vfwcash/api.rb +48 -0
  24. data/lib/vfwcash/cli.rb +195 -0
  25. data/lib/vfwcash/controller.rb +83 -0
  26. data/lib/vfwcash/version.rb +3 -0
  27. data/lib/vfwcash.rb +90 -0
  28. data/pdf_examples/audit_201507.pdf +2826 -0
  29. data/pdf_examples/balance_201508.pdf +2283 -0
  30. data/pdf_examples/controllers/checkbooks_controller.rb +99 -0
  31. data/pdf_examples/ledger_201504.pdf +5758 -0
  32. data/pdf_examples/ledger_summary.pdf +5719 -0
  33. data/pdf_examples/register_201508.pdf +1157 -0
  34. data/pdf_examples/split_201508.pdf +4930 -0
  35. data/pdf_examples/views/checkbooks/balance.html.slim +53 -0
  36. data/pdf_examples/views/checkbooks/between.html.slim +53 -0
  37. data/pdf_examples/views/checkbooks/index.html.slim +57 -0
  38. data/pdf_examples/views/checkbooks/ledger.html.slim +58 -0
  39. data/pdf_examples/views/checkbooks/register.html.slim +44 -0
  40. data/pdf_examples/views/checkbooks/split.html.slim +45 -0
  41. data/pdf_examples/views/checkbooks/summary.html.slim +56 -0
  42. data/vfwcash.gemspec +31 -0
  43. metadata +198 -0
@@ -0,0 +1,189 @@
1
+ require "yaml/store"
2
+
3
+ module Vfwcash
4
+
5
+ class Gcash
6
+ # gcash is the primary interface to the GNUCash database
7
+ # The initializer sets attributes based on data in the db and from the config file
8
+ # that is common to all reports.
9
+
10
+ # API calls provide informtion needed for specific reports.
11
+
12
+ attr_accessor :balances, :checking, :savings, :checking_funds,:savings_funds,
13
+ :dates, :bmonth, :checking_acct, :savings_acct, :tmonths, :config
14
+
15
+ def initialize(config)
16
+ @config = config
17
+ @checking_acct = @config[:checking_acct]
18
+ @savings_acct = @config[:savings_acct]
19
+ @checking_funds = CashAccount.find_by(name:@checking_acct).children.pluck(:name)
20
+ @savings_funds = CashAccount.find_by(name:@savings_acct).children.pluck(:name)
21
+ @dates = Vfwcash.transaction_range
22
+ set_tmonths
23
+ end
24
+ # COMMON Methods
25
+ def set_tmonths
26
+ @tmonths = []
27
+ first = @dates.first
28
+ last = @dates.last
29
+ curr = first
30
+ while curr < last do
31
+ @tmonths << "#{curr.year}#{curr.month.to_s.rjust(2,'0')}"
32
+ curr += 1.month
33
+ end
34
+ end
35
+
36
+ def get_fund_balances(bdate,edate)
37
+ @balances = {}
38
+ @balances[:checking] = {bbalance:0,diff:0,debits:0,credits:0,ebalance:0}
39
+ @balances[:savings] = {bbalance:0,diff:0,debits:0,credits:0,ebalance:0}
40
+ accts = @checking_funds + @savings_funds
41
+ accts.each do |f|
42
+ acct = CashAccount.find_by(name:f)
43
+ @balances[f] = acct.balances_between(bdate,edate)
44
+ if @checking_funds.include?(f)
45
+ sum_from_to(@balances[f],@balances[:checking])
46
+ else
47
+ sum_from_to(@balances[f],@balances[:savings])
48
+ end
49
+ end
50
+ @checking = @balances[:checking]
51
+ @savings = @balances[:savings]
52
+ end
53
+
54
+ def sum_from_to(ffund,tfund)
55
+ ffund.each do |k,v|
56
+ tfund[k] += v
57
+ end
58
+ end
59
+
60
+ def get_all_balances
61
+ balances = {checking:{},savings:{}}
62
+ accts = @checking_funds + @savings_funds
63
+ accts.each do |f|
64
+ acct = CashAccount.find_by(name:f)
65
+ balances[f] = {}
66
+ tmonths.each do |m|
67
+ bom = Date.parse(m+"01")
68
+ eom = bom.end_of_month
69
+ balances[f][m] = get_fund_balances(bom,eom)
70
+ balances[:checking][m] = @checking
71
+ balances[:savings][m] = @savings
72
+ end
73
+ end
74
+ @balances = balances
75
+ @checking = @balances[:checking]
76
+ @saving = @balances[:savings]
77
+ end
78
+
79
+ # REPORT Specific Methods
80
+ def between_balance(from,to)
81
+ between = {}
82
+ accts = @checking_funds + @savings_funds
83
+ accts.each do |f|
84
+ acct = CashAccount.find_by(name:f)
85
+ between[f] = acct.balances_between(from,to)
86
+ end
87
+ between
88
+ end
89
+
90
+ def audit_api(report_date)
91
+ date = Vfwcash.set_date(report_date)
92
+ boq = date.beginning_of_quarter
93
+ eoq = boq.end_of_quarter
94
+ if eoq.month >= date.month
95
+ boq = (boq - 1.month).beginning_of_quarter
96
+ eoq = boq.end_of_quarter
97
+ end
98
+ get_fund_balances(boq,eoq)
99
+ rbalances = @balances
100
+ rbalances["Cash"] = {bbalance:100000,ebalance:100000,debits:0,credits:0}
101
+ rbalances[:dates] = {boq:boq,eoq:eoq, report_date:date}
102
+ rbalances
103
+ end
104
+
105
+ def split_ledger_api(date)
106
+ response = {rows:split_ledger(date)}
107
+ response[:balances] = {checking:@checking}
108
+ response[:month] = @bmonth
109
+ return response
110
+ end
111
+
112
+ def split_ledger(date)
113
+ @bmonth = Vfwcash.yyyymm(date)
114
+ trans = Tran.month_transactions(date)
115
+ lines = []
116
+ b = @checking[:bbalance]
117
+ trans.each do |t|
118
+ date = Date.parse(t.post_date)
119
+ line = {date: date.strftime("%m/%d/%Y"),num:t.num,desc:t.description,
120
+ checking:{db:0,cr:0},details:[],balance:0, memo:nil,r:nil}
121
+ t.splits.each do |s|
122
+ details = s.details
123
+ if details[:name].include?("#{@checking_acct}:")
124
+ line[:checking][:db] += details[:db]
125
+ line[:checking][:cr] += details[:cr]
126
+ b += (details[:db] - details[:cr])
127
+ line[:balance] = b
128
+ line[:r] = details[:r]
129
+ else
130
+ line[:balance] = b
131
+ if line[:memo].nil?
132
+ line[:memo] = details[:name]
133
+ else
134
+ line[:memo] = "- Split Transaction -"
135
+ end
136
+ end
137
+ line[:details] << details
138
+ end
139
+ lines << line
140
+ end
141
+ lines
142
+ end
143
+
144
+ def month_ledger_api(date)
145
+ response = {rows:month_ledger(date)}
146
+ fund_bal = {}
147
+ @checking_funds.each do |f|
148
+ fund_bal[f] = @balances[f]
149
+ end
150
+ response[:balances] = {savings:@savings,checking:@checking,funds:fund_bal}
151
+ response[:funds] = {savings:@savings_funds,checking:@checking_funds}
152
+ response[:month] = @bmonth
153
+ return response
154
+ end
155
+
156
+ def month_ledger(date)
157
+ @bmonth = Vfwcash.yyyymm(date)
158
+ trans = Tran.month_transactions(date)
159
+ lines = []
160
+ trans.each do |t|
161
+ date = Date.parse(t.post_date)
162
+ line = {date: date.strftime("%m/%d/%Y"),num:t.num,r:nil,desc:t.description,checking:{db:0,cr:0}}
163
+ @checking_funds.each do |f|
164
+ line[f] = {db:0,cr:0}
165
+ end
166
+ line[:savings] = {db:0,cr:0}
167
+ t.splits.each do |s|
168
+ details = s.details
169
+ if details[:name].include?("#{@checking_acct}:")
170
+ line[details[:fund]][:db] += details[:db]
171
+ line[details[:fund]][:cr] += details[:cr]
172
+ line[:checking][:db] += details[:db]
173
+ line[:checking][:cr] += details[:cr]
174
+ line[:r] = details[:r]
175
+ elsif details[:name].include?("#{@savings_acct}:")
176
+ line[:savings][:db] += details[:db]
177
+ line[:savings][:cr] += details[:cr]
178
+ line[:r] = details[:r]
179
+ end
180
+ end
181
+
182
+ lines << line
183
+ end
184
+ lines
185
+ end
186
+
187
+ end
188
+
189
+ end
@@ -0,0 +1,109 @@
1
+ class Pdf::Ledger < Prawn::Document
2
+ attr_accessor :response, :date, :cwidths
3
+
4
+ def initialize(date,cash)
5
+ super( top_margin: 35, page_layout: :landscape)
6
+ @date = Vfwcash.set_date(date).beginning_of_month
7
+ @config = cash.config
8
+ cash.get_fund_balances(@date,@date.end_of_month)
9
+ @response = cash.month_ledger_api(@date)
10
+
11
+ make_pdf
12
+ number_pages "#{Date.today} - Page <page> of <total>", { :start_count_at => 0, :page_filter => :all, :at => [bounds.right - 100, 0], :align => :right, :size => 6 }
13
+ end
14
+
15
+ def header
16
+ arr = ["Date", "Num","R", "Description", {content: "+ Checking -",colspan:2, align: :center}]
17
+ @cwidths = [36, 22,8,108,32,32]
18
+ @response[:funds][:checking].each do |f|
19
+ arr << {content:"+ #{f} -",colspan:2, align: :center}
20
+ @cwidths << 30
21
+ @cwidths << 30
22
+ end
23
+ arr << {content:"+ Savings -",colspan:2, align: :center}
24
+ @cwidths << 30
25
+ @cwidths << 30
26
+ arr
27
+ end
28
+
29
+ def bbalance_row
30
+ cntnt = "Beginning balance #{@response[:month]}: "
31
+ cntnt += "Total Current Assets #{money(@response[:balances][:savings][:bbalance] + @response[:balances][:checking][:bbalance])}"
32
+
33
+ arr = [{content: cntnt,colspan:4,font_style: :bold}]
34
+ arr << {content: money(@response[:balances][:checking][:bbalance]),colspan:2, align: :center,font_style: :bold}
35
+ @response[:funds][:checking].each do |f|
36
+ arr << { content: money(@response[:balances][:funds][f][:bbalance]),colspan:2, align: :center,font_style: :bold}
37
+ end
38
+ arr << {content: money(@response[:balances][:savings][:bbalance]),colspan:2, align: :center,font_style: :bold}
39
+ arr
40
+ end
41
+
42
+ def ebalance_row
43
+ cntnt = "Ending balance #{@response[:month]}: "
44
+ cntnt += "Total Current Assets #{money(@response[:balances][:savings][:ebalance] + @response[:balances][:checking][:ebalance])}"
45
+
46
+ arr = [{content: cntnt,colspan:4,font_style: :bold}]
47
+ arr << {content: money(@response[:balances][:checking][:ebalance]),colspan:2, align: :center,font_style: :bold}
48
+ @response[:funds][:checking].each do |f|
49
+ arr << { content: money(@response[:balances][:funds][f][:ebalance]),colspan:2, align: :center,font_style: :bold}
50
+ end
51
+ arr << {content: money(@response[:balances][:savings][:ebalance]),colspan:2, align: :center,font_style: :bold}
52
+ arr
53
+ end
54
+
55
+ def summary_row
56
+ cntnt = "Debits/Credits Summary #{@response[:month]}: "
57
+ arr = [{content: cntnt,colspan:4,font_style: :bold}]
58
+ arr << {content: money(@response[:balances][:checking][:debits]), align: :right}
59
+ arr << {content: money(@response[:balances][:checking][:credits]), align: :right}
60
+ @response[:funds][:checking].each do |f|
61
+ arr << {content: money(@response[:balances][:funds][f][:debits]), align: :right}
62
+ arr << {content: money(@response[:balances][:funds][f][:credits]), align: :right}
63
+ end
64
+ arr << {content: money(@response[:balances][:savings][:debits]), align: :right}
65
+ arr << {content: money(@response[:balances][:savings][:credits]), align: :right}
66
+ arr
67
+ end
68
+
69
+ def make_pdf
70
+ font_size 6
71
+ build_table
72
+ draw_table
73
+ end
74
+
75
+ def build_table
76
+ @rows = [header]
77
+ @rows << bbalance_row
78
+ @response[:rows].each do |r|
79
+ arr = []
80
+ r.each do |k,v|
81
+ if v.class == Hash
82
+ arr << (v[:db].zero? ? nil :{content: (money(v[:db])), align: :right})
83
+ arr << (v[:cr].zero? ? nil :{content: (money(v[:cr])), align: :right})
84
+ else
85
+ arr << v
86
+ end
87
+ end
88
+ @rows << arr
89
+ end
90
+ @rows << summary_row
91
+ @rows << ebalance_row
92
+ end
93
+
94
+ def draw_table
95
+ text "#{@config[:post][:post]} General Ledger - #{@date}", style: :bold, align: :center
96
+ move_down(2)
97
+ e = make_table @rows,row_colors: ["F8F8F8", "FFFFFF"],:cell_style => {:padding => [1, 2, 2, 1],border_color:"E0E0E0"},
98
+ :column_widths => @cwidths, header:true do
99
+
100
+ row(0).font_style = :bold
101
+ end
102
+ e.draw
103
+ end
104
+
105
+ def money(int)
106
+ Vfwcash.money(int)
107
+ end
108
+
109
+ end
@@ -0,0 +1,54 @@
1
+ class Pdf::Register < Prawn::Document
2
+ attr_accessor :response, :date
3
+
4
+ def initialize(date,cash)
5
+ super( top_margin: 35)
6
+ @date = Vfwcash.set_date(date).beginning_of_month
7
+ @config = cash.config
8
+ cash.get_fund_balances(@date,@date.end_of_month)
9
+ @response = cash.split_ledger_api(@date)
10
+ make_pdf
11
+ number_pages "#{Date.today} - Page <page> of <total>", { :start_count_at => 0, :page_filter => :all, :at => [bounds.right - 100, 0], :align => :right, :size => 6 }
12
+ end
13
+
14
+ def header
15
+ arr = ["Date", "Num","Description","Account","R","Debits","Credits", "Balance"]
16
+ end
17
+
18
+ def balance_row
19
+ [{content:'',colspan: 2},"Beginning Balance",nil,nil,nil,nil,{content: money(@response[:balances][:checking][:bbalance]),align: :right}]
20
+ end
21
+
22
+ def make_pdf
23
+ font_size 7
24
+ build_table
25
+ draw_table
26
+ end
27
+
28
+ def build_table
29
+ @rows = [header]
30
+ @rows << balance_row
31
+ @response[:rows].each do |row|
32
+ arr = [row[:date],row[:num],row[:desc],row[:memo],row[:r]]
33
+ arr << (row[:checking][:db].zero? ? nil : {content: money(row[:checking][:db]), align: :right})
34
+ arr << (row[:checking][:cr].zero? ? nil : {content: money(row[:checking][:cr]), align: :right})
35
+ arr << (row[:balance].zero? ? nil : {content: money(row[:balance]), align: :right})
36
+ @rows << arr
37
+ end
38
+ end
39
+
40
+ def draw_table
41
+ text "#{@config[:post][:post]} Checkbook Register - #{@date}", style: :bold, align: :center
42
+ move_down(2)
43
+ e = make_table @rows,row_colors: ["F8F8F8", "FFFFFF"],:cell_style => {:padding => [1, 2, 2, 1],border_color:"E0E0E0"},
44
+ :column_widths => [40, 24, 150,110,10,40,40,40,40], header:true do
45
+ row(0).font_style = :bold
46
+ end
47
+ e.draw
48
+ end
49
+
50
+ def money(int)
51
+ Vfwcash.money(int)
52
+ end
53
+
54
+ end
@@ -0,0 +1,26 @@
1
+ class Split < SqliteBase
2
+ self.primary_key = 'guid'
3
+ belongs_to :tran, foreign_key: 'tx_guid'
4
+ belongs_to :cash_account, foreign_key: 'account_guid'
5
+
6
+ def amount
7
+ return "#{self.value_num / self.value_denom}.#{self.value_num % self.value_denom}"
8
+ end
9
+
10
+ def details
11
+ acct = self.cash_account
12
+ fund = acct.name
13
+ parent = acct.parent
14
+ acct_name = parent.present? ? "#{parent.name}:#{acct.name}" : acct.name
15
+
16
+ amt = self.value_num
17
+ if amt.to_f < 0
18
+ credit = amt * -1
19
+ debit = 0
20
+ else
21
+ credit = 0
22
+ debit = amt
23
+ end
24
+ return {fund:fund,name:acct_name,cr:credit,db:debit, memo:self.memo, r:self.reconcile_state}
25
+ end
26
+ end
@@ -0,0 +1,69 @@
1
+ class Pdf::SplitLedger < Prawn::Document
2
+ attr_accessor :response, :date
3
+
4
+ def initialize(date,cash)
5
+ super( top_margin: 35)
6
+ @date = Vfwcash.set_date(date).beginning_of_month
7
+ @config = cash.config
8
+ cash.get_fund_balances(@date,@date.end_of_month)
9
+ @response = cash.split_ledger_api(@date)
10
+ make_pdf
11
+ number_pages "#{Date.today} - Page <page> of <total>", { :start_count_at => 0, :page_filter => :all, :at => [bounds.right - 100, 0], :align => :right, :size => 6 }
12
+ end
13
+
14
+ def header
15
+ arr = ["Date", "Num","Description","Account","R","Debits","Credits", "Balance"]
16
+ end
17
+
18
+ def balance_row
19
+ [{content:'',colspan: 2},"Beginning Balance",nil,nil,nil,nil,{content: money(@response[:balances][:checking][:bbalance]),align: :right}]
20
+ end
21
+
22
+ def make_pdf
23
+ font_size 7
24
+ build_table
25
+ draw_table
26
+ end
27
+
28
+ def build_table
29
+ @rows = [header]
30
+ @rows << balance_row
31
+ @response[:rows].each do |row|
32
+ arr = [row[:date],row[:num],row[:desc],nil,nil]
33
+ arr << (row[:checking][:db].zero? ? nil : {content: money(row[:checking][:db]), align: :right})
34
+ arr << (row[:checking][:cr].zero? ? nil : {content: money(row[:checking][:cr]), align: :right})
35
+ arr << (row[:balance].zero? ? nil : {content: money(row[:balance]), align: :right})
36
+ @rows << arr
37
+ row[:details].each do |d|
38
+ arr = [{content:'',colspan: 2},d[:memo], d[:name],d[:r],
39
+ (d[:db].zero? ? nil : {content: money(d[:db]), align: :right}),
40
+ (d[:cr].zero? ? nil : {content: money(d[:cr]), align: :right}),
41
+ nil
42
+ ]
43
+ @rows << arr
44
+ end
45
+ end
46
+ end
47
+
48
+ def draw_table
49
+ text "#{@config[:post][:post]} Split Ledger - #{@date}", style: :bold, align: :center
50
+ move_down(2)
51
+ e = make_table @rows,:cell_style => {:padding => [1, 2, 2, 1],border_color:"E0E0E0"},
52
+ :column_widths => [40, 24, 150,100,10,40,40,40,40], header:true do
53
+ row(0).font_style = :bold
54
+ i = row_length - 1
55
+ 0.upto(i) do |j|
56
+ if cells[j,0].content.blank?
57
+ row(j).style(:background_color => 'F8F8F8')
58
+ end
59
+ end
60
+ end
61
+ e.draw
62
+ end
63
+
64
+ def money(int)
65
+ Vfwcash.money(int)
66
+ end
67
+
68
+
69
+ end
@@ -0,0 +1,10 @@
1
+ class SqliteBase < ActiveRecord::Base
2
+ self.logger = Logger.new(STDERR)
3
+ self.logger.level = 3
4
+
5
+ establish_connection(
6
+ :adapter => 'sqlite3',
7
+ :database => Vfwcash::Config[:database]
8
+ )
9
+ self.abstract_class = true
10
+ end
@@ -0,0 +1,98 @@
1
+ class Pdf::Summary < Prawn::Document
2
+ attr_accessor :cash, :date, :cwidths
3
+
4
+ def initialize(cash)
5
+ super( top_margin: 35, page_layout: :landscape)
6
+ @cash = cash
7
+ @cash.get_all_balances
8
+ @config = @cash.config
9
+ make_pdf
10
+ number_pages "#{Date.today} - Page <page> of <total>", { :start_count_at => 0, :page_filter => :all, :at => [bounds.right - 100, 0], :align => :right, :size => 6 }
11
+ end
12
+
13
+ def header
14
+ arr = ["General Ledger Summary for #{@cash.dates}", {content: "+ Checking -",colspan:2, align: :center}]
15
+ @cwidths = [160,32,32]
16
+ @cash.checking_funds.each do |f|
17
+ arr << {content:"+ #{f} -",colspan:2, align: :center}
18
+ @cwidths << 30
19
+ @cwidths << 30
20
+ end
21
+ arr << {content:"+ Savings -",colspan:2, align: :center}
22
+ @cwidths << 30
23
+ @cwidths << 30
24
+ arr
25
+ end
26
+
27
+ def bbalance_row(m)
28
+ tca = @cash.balances[:savings][m][:bbalance] + @cash.balances[:checking][m][:bbalance]
29
+ cntnt = " #{m} Beginning Balance (Current Assets #{money(tca)} )"
30
+ arr = [{content: cntnt,font_style: :bold}]
31
+ arr << {content: money(@cash.balances[:checking][m][:bbalance]),colspan:2, align: :center,font_style: :bold}
32
+ @cash.checking_funds.each do |f|
33
+ arr << { content: money(@cash.balances[f][m][:bbalance]),colspan:2, align: :center,font_style: :bold}
34
+ end
35
+ arr << {content: money(@cash.balances[:savings][m][:bbalance]),colspan:2, align: :center,font_style: :bold}
36
+ arr
37
+ end
38
+
39
+ def ebalance_row(m)
40
+ tca = @cash.balances[:savings][m][:bbalance] + @cash.balances[:checking][m][:bbalance]
41
+ cntnt = " #{m} Current Balance (Current Assets #{money(tca)} )"
42
+ arr = [{content: cntnt,font_style: :bold}]
43
+ arr << {content: money(@cash.balances[:checking][m][:ebalance]),colspan:2, align: :center,font_style: :bold}
44
+ @cash.checking_funds.each do |f|
45
+ arr << { content: money(@cash.balances[f][m][:ebalance]),colspan:2, align: :center,font_style: :bold}
46
+ end
47
+ arr << {content: money(@cash.balances[:savings][m][:ebalance]),colspan:2, align: :center,font_style: :bold}
48
+ arr
49
+ end
50
+
51
+ def summary_row(m)
52
+ pl = @cash.balances[:savings][m][:diff] + @cash.balances[:checking][m][:diff]
53
+ cntnt = "Total Debits/Credits (Profit/Loss: #{money(pl)})"
54
+ arr = [{content: cntnt,font_style: :bold}]
55
+ arr << {content: money(@cash.balances[:checking][m][:debits]), align: :right}
56
+ arr << {content: money(@cash.balances[:checking][m][:credits]), align: :right}
57
+ @cash.checking_funds.each do |f|
58
+ arr << {content: money(@cash.balances[f][m][:debits]), align: :right}
59
+ arr << {content: money(@cash.balances[f][m][:credits]), align: :right}
60
+ end
61
+ arr << {content: money(@cash.balances[:savings][m][:debits]), align: :right}
62
+ arr << {content: money(@cash.balances[:savings][m][:credits]), align: :right}
63
+ arr
64
+ end
65
+
66
+
67
+ def make_pdf
68
+ font_size 6
69
+ build_table
70
+ draw_table
71
+ end
72
+
73
+ def build_table
74
+ @rows = [header]
75
+ @cash.tmonths.each do |m|
76
+ @rows << bbalance_row(m)
77
+ @rows << summary_row(m)
78
+ end
79
+ m = @cash.tmonths.last
80
+ @rows << ebalance_row(m)
81
+ end
82
+
83
+ def draw_table
84
+ text "#{@config[:post][:post]} General Ledger Summary", style: :bold, align: :center
85
+ move_down(2)
86
+ e = make_table @rows,row_colors: ["F8F8F8", "FFFFFF"],:cell_style => {:padding => [1, 2, 2, 1],border_color:"E0E0E0"},
87
+ :column_widths => @cwidths, header:true do
88
+
89
+ row(0).font_style = :bold
90
+ end
91
+ e.draw
92
+ end
93
+
94
+ def money(int)
95
+ Vfwcash.money(int)
96
+ end
97
+
98
+ end
@@ -0,0 +1,12 @@
1
+ class Tran < SqliteBase
2
+ self.table_name = "transactions"
3
+ self.primary_key = 'guid'
4
+
5
+ has_many :splits, foreign_key: 'tx_guid'
6
+
7
+ def self.month_transactions(date)
8
+ month = Vfwcash.yyyymm(date)
9
+ trans = Tran.where('transactions.post_date BETWEEN ? and ?',month+"00",month+"32").order(:post_date,:num)
10
+ end
11
+
12
+ end
Binary file
Binary file
@@ -0,0 +1,95 @@
1
+ ---
2
+ # path to you exported or saved sqlite3 GnuCash database
3
+ :database: "/Users/salex/Work/vfwcash/config/vfwcash.gnucash"
4
+ # GnuCash parent account names for Checking and Savings accounts
5
+ :checking_acct: Checking Account
6
+ :savings_acct: Savings Account
7
+ # Balance from bank statement and GnuCash on last Bank Balance reconciliation
8
+ # GnuCash stores all amounts (money) as integers or Pennies in US Dollars
9
+ # to be consistent, follow that convention in the config file
10
+ :checking:
11
+ :balance: 1783700
12
+ :outstanding: 20000
13
+ :date:
14
+ # The rest of the configuration data is used to format the Trustee' Report of Audit
15
+ :qm:
16
+ :name: Steven V Quartermaster
17
+ :address: 405 Somestreet Hls
18
+ :city: Sometown AL, 35901
19
+ :post:
20
+ :name: Some name
21
+ :post: VFW Post 66666
22
+ :numb: 66666
23
+ :address: 817 somestreet Dr
24
+ :city: Sometown AL, 35901
25
+ :department: Alabama
26
+ # Questions and Answers from the operations section
27
+ :operations:
28
+ :a:
29
+ :ques: a. Have required payroll deductions been made?
30
+ :answ: 'Yes'
31
+ :b:
32
+ :ques: b. Have payments been made to the proper State & Federal agencies this
33
+ quarter?
34
+ :answ: 'Yes'
35
+ :c:
36
+ :ques: c. Have Sales Taxes been collected and paid?
37
+ :answ: 'Yes'
38
+ :d:
39
+ :ques: d. Are Club employees bonded?
40
+ :answ: 'Yes'
41
+ :e:
42
+ :ques: e. Amount of outstanding bills?
43
+ :answ: 0
44
+ :f:
45
+ :ques: f. Value of Real Estate?
46
+ :answ: 58850000
47
+ :g:
48
+ :ques: g. Amount of Liability Insurance?
49
+ :answ: 30000000
50
+ :h:
51
+ :ques: h. Owed on Mortgages and Loans?
52
+ :answ: 0
53
+ :i:
54
+ :ques: i. Value of Personal Property?
55
+ :answ: 4680000
56
+ :j:
57
+ :ques: j. Amount of Property Insurance?
58
+ :answ: 31350000
59
+ # Date Audit report signed or submitted
60
+ :date: '2015-07-14'
61
+ :bond:
62
+ :name: Tallman Insurance Agency
63
+ :amount: 8000000
64
+ :to: '2016-09-30'
65
+ # a cross reference to your fund names in GnuCash
66
+ :funds:
67
+ 1:
68
+ :fund: Dues
69
+ :text: 1. National and Department Dues (Per Capitia Tax)
70
+ 2:
71
+ :fund: Fee
72
+ :text: 2. Admission or Application Fees (Department)
73
+ 3:
74
+ :fund: General
75
+ :text: 3. Post General Fund
76
+ 4:
77
+ :fund: Relief
78
+ :text: 4. Post Relief Fund (Poppy Profits, Donations, etc.)
79
+ 5:
80
+ :fund: Reserve
81
+ :text: 5. Post Dues Reserve Fund (See Sec. 218, Manual of Procedure)
82
+ 6:
83
+ :fund: Building
84
+ :text: 6. Post Home Building Fund (Including Savings but Not Real Estate)
85
+ 7:
86
+ :fund: Cash
87
+ :text: 7. Post Canteen or Club Fund
88
+ 8:
89
+ :fund: Temporary
90
+ :text: 8. Temporary Fund
91
+ 9:
92
+ # Savings is not a real fund, but is computed as sum of all funds that are not
93
+ # a child of 'Checking Account'. The symbol ':savings' is used to access that sum
94
+ :fund: :savings
95
+ :text: 9. Bonds and Investments Not Credited to Funds