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
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6c6e5a900ec2ed140185809d599be6066c2eb284
4
+ data.tar.gz: ea95a2c217a11977f7dc03ff80d9909634ebd35e
5
+ SHA512:
6
+ metadata.gz: 607cfc531d9013adb9c8e4a34e611cbac569781b408db6a29bb6771a504529481f33f68b3ee5970e9297723a2c824c88e64306d81dad35b638579a91dffbf2ba
7
+ data.tar.gz: 92e9020be5cd383e054ef8e49d234bbc43959aa3fc54a9a20f1b555c5d52571e6c66176434205827d1587984d00c07b2a1bdd63e004b2b5458c84a1607ba2dec
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ *.log
15
+ /config/
16
+ /pdf/
17
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in vfwcash.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Steve Alex
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,107 @@
1
+ # VFWCash
2
+
3
+ A beta version of a Ruby gem that provides a Command Line Interface (CLI) to generates VFW formated reports(pdf) from a GnuCash book. It also provides an pseudo API to access the same reports and/or data if accessing the reports from another application.
4
+
5
+ ## Why
6
+
7
+ VFW Quartermasters are required to keep Post accounting books. Procedures only address manual/paper ledgers and reports.
8
+ This is fine for a small Post that only writes a few checks a month. Automated ledgers are allowed, but paper backup is
9
+ required.
10
+
11
+ I was not about to use a paper ledger and decided to use GnuCash (http://gnucash.org) several years ago. GnuCash is a full fledged double entry accounting system somewhere between Quicken and Quickbooks and it's free!
12
+ I had developed a Rails Web Based system to help me with my Quartermaster tasks, but is was fairly customized, including my
13
+ interface to the GnuCash data.
14
+ GnuCash was set up to use the VFW's version of Fund Based Accounting. This became fairly simple and
15
+ could be used by any Post or any organization that uses fund based accounting (most non-profit organizations)
16
+ I'll point out that we do not use
17
+ GnuCash as our main accounting system, although we could. We have an Accountant that handles mainly payroll and taxes and we send them the information they need (in reports or source documents). We basically use it as a checkbook, fund manager and enter stuff from the accountant (payroll checks, eft or forms to pay taxes etc). I also summarize income and expense from our customized post management system (sales, donations, etc).
18
+
19
+ I wanted to share my work, but I work on a Mac and setting up Ruby on Rails on Windows would probably be more than most VFW
20
+ users could handle. Setting up Ruby on Windows is fairly straight forward (http://rubyinstaller.org) and so I decided to
21
+ write a command line interface to the models and Prawn PDF reports I had developed. Hopefully I can document how to use the CLI on Windows, if I can remember how to use Windows! I also replaced my GnuCash interface in our custom application to use VFWCash
22
+
23
+ ## Installation
24
+
25
+ The gem has not been uploaded to Ruby Gems during beta testing, but you can install it locally by cloning vfwcash
26
+
27
+ ```ruby
28
+ git git@github.com:salex/vfwcash.git
29
+ ```
30
+
31
+ And then execute:
32
+
33
+ $ cd vfwcash
34
+ $ rake build
35
+ $ rake install
36
+ $ mkdir ~./some_rails_like_app_directory
37
+ $ cd ~./some_rails_like_app_directory
38
+ $ vfwcash help
39
+ $ vfwcash install -db
40
+
41
+ Or work with the development version:
42
+
43
+ $ cd vfwcash
44
+ $ bundle
45
+ $ bundle exec bin/vfwcash help
46
+ -> commands
47
+ $ bundle exec bin/vfwcash help install
48
+ -> install help
49
+ $ bundle exec bin/vfwcash install -db
50
+
51
+ ## Usage
52
+
53
+ The Wiki has brief documentation on how to set up GnuCash for fund based accounting, but for
54
+ now the vfwcash install command with a --db option will install a small sqlite3 database in the config directory, That db
55
+ only contains a few transactions for the months April through August of 2015. You don't need GnuCash
56
+ installed to use the CLI, unless you want to add transactions.
57
+
58
+ You must edit the config/vfwcash.yml file after it is installed and set the absolute path to the sqlite3 database and other attributes that define you Post and your GnuCash setup.
59
+
60
+ GunCash's default data format is XML, but there is an option to use a sqlite3 database in the default download (Postgresql or Mysql if you want to roll your own). I still use the
61
+ XML version because of a built-in backup scheme. Since I'm only concerned with reports a few times a month, I use `Save As` to create a sqlite3 copy of the database for reporting.
62
+ The VFWCash database is read-only so it could point to the primary db, but that brings up single-user problems (GnuCash implementation) that locks the db to a single user.
63
+
64
+ Once installed and configured, `vwfcash help` will display:
65
+
66
+ Commands:
67
+ vfwcash --dates, -d # print date format options
68
+ vfwcash --version, -v # print the version
69
+ vfwcash audit [DATE] # Trustee Audit Report
70
+ vfwcash balance [DATE] # Monthly Fund Balance Summary
71
+ vfwcash between date1 date2 # Get balances between two dates
72
+ vfwcash help [COMMAND] # Describe available commands or one specific command
73
+ vfwcash install --dir --db # Install config files and optional test DB in pwd or pwd/--dir
74
+ vfwcash ledger [DATE] # General Ledger report by month
75
+ vfwcash register [DATE] # Checkbook register report
76
+ vfwcash split [DATE] # Checkbook split register report
77
+ vfwcash summary [DATE] # General Ledger Summary Report
78
+
79
+ There are 7 basic reports derived from GnuCash accounts, transactions and splits. You can view examples
80
+ of these reports in the folder [`pdf_examples`](https://github.com/salex/vfwcash/tree/master/pdf_examples) on github
81
+
82
+ * register
83
+ * A checkbook like register with transactions by date and number/ Single line summarizing transaction, no splits
84
+ * split
85
+ * The same as register but with all splits (there will be at least two) displayed on a separate line
86
+ * ledger
87
+ * A general ledger by date and number with a debit/credit column for each fund account. The report includes starting and ending balances, and summed credits and debits for the month
88
+ * summary
89
+ * A general ledger for all months in db, but only displays summary balances, debits and credits by month.
90
+ * audit
91
+ * Produces a PDF version of VFW Form: Trustees Audit Report (summarizes transactions by quarter)
92
+ * balance
93
+ * Like the summary command, but only produces a summary of fund balances, debits and credits for a single month in a compact format.
94
+ * between
95
+ * Same format as balance, but produces a summary between any two dates.
96
+
97
+ ### API
98
+
99
+ I will put something in the wiki to describe how to use VFWCash from another application at some point. There is another controller to access the same reports or data from another application. There is a sample RoR controller and views in the examples directory that uses this option.
100
+
101
+ ## Contributing
102
+
103
+ 1. Fork it ( https://github.com/salex/vfwcash/fork )
104
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
105
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
106
+ 4. Push to the branch (`git push origin my-new-feature`)
107
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/bin/vfwcash ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'vfwcash'
4
+ Vfwcash.valid_root? unless ARGV.include? 'install'
5
+ Vfwcash::Checkbook.start( ARGV )
@@ -0,0 +1,228 @@
1
+ module Pdf
2
+ class Audit < Prawn::Document
3
+ attr_accessor :cur, :config, :balances
4
+ def initialize(date,cash)
5
+ super( top_margin: 35)
6
+ @date = Vfwcash.set_date(date).beginning_of_month
7
+ @layout = {top:bounds.height.to_i,right:bounds.width.to_i,left:0,bottom:0,cursor:cursor}
8
+ @config = cash.config
9
+ # cash.get_balances
10
+ @balances = cash.audit_api(@date)
11
+ make_pdf
12
+ end
13
+
14
+ def make_pdf
15
+ @cur = @layout[:top]
16
+ font_size 9
17
+ # get_config
18
+ header
19
+ report
20
+ funds
21
+ operations
22
+ reconcile
23
+ certify
24
+ verify
25
+ quartermaster
26
+ trustees
27
+ bonding
28
+ commander
29
+ number_pages "VFW Post 8600 Form - Page <page> of <total>", { :start_count_at => 0, :page_filter => :all, :at => [bounds.right - 100, 0], :align => :right, :size => 6 }
30
+ end
31
+
32
+
33
+ def header
34
+ bounding_box([0,@cur], width: 80, height:80) do
35
+ image "#{Vfwcash::LibPath}/templates/vfw-gray.png",height:50
36
+ end
37
+
38
+ bounding_box([0, @cur], :width => @layout[:right], :height => 30) do
39
+ draw_text "TRUSTEES' REPORT OF AUDIT of", at:[100,15], style: :bold, size:12
40
+ end
41
+ @cur -= 32
42
+ end
43
+
44
+ def report
45
+ bounding_box([70, @cur], :width => @layout[:right] - 70, :height => 50) do
46
+ text_box "The Books and Records of the Quartermaster and Adjutant of: <strong><u>#{@config[:post][:name]} - #{@config[:post][:post]}</u></strong>", at:[30,50], inline_format:true
47
+ text_box "Department of <strong><u> #{@config[:post][:department]} </u></strong> for Fiscal Quarter ending: <strong><u>#{@balances[:dates][:eoq]}</u></strong>", at:[30,35], inline_format:true
48
+ text_box "Fiscal Quarter <strong><u>#{@balances[:dates][:boq]} to #{@balances[:dates][:eoq]}</u></strong>", at:[30,20], inline_format:true
49
+
50
+ end
51
+ @cur -= 52
52
+
53
+ end
54
+
55
+ def funds
56
+ bounding_box([0, @cur], :width => @layout[:right], :height => 180) do
57
+ rows = []
58
+ h = [ "FUNDS",
59
+ "10. Net Cash Balances at Beginning of Quarter",
60
+ "11. Receipts During Quarter",
61
+ "12. Expenditures During Quarter",
62
+ "13. Net Cash Balances at End of Quarter"]
63
+ rows << h
64
+ bb = @eb = cr = db = 0
65
+ @config[:funds].each do |f,v|
66
+ bal = @balances[v[:fund]]
67
+ if bal.present?
68
+ bb += bal[:bbalance]
69
+ @eb += bal[:ebalance]
70
+ db += bal[:debits]
71
+ cr += bal[:credits]
72
+ rows << [v[:text], money(bal[:bbalance]),money(bal[:debits]),money(bal[:credits]),money(bal[:ebalance])]
73
+ end
74
+ end
75
+ rows << [' ',nil,nil,nil,nil]
76
+ rows << ['10. Total',money(bb),money(db),money(cr),"(15) " + money(@eb)]
77
+ font_size 8
78
+ e = make_table rows,:cell_style => {:padding => [1, 2, 2, 1] ,border_color:"000000"},
79
+ :column_widths => [268, 68,68,68,68] do
80
+ row(0).column(0).font_style = :bold
81
+ row(0).column(0).size = 10
82
+ row(0).column(1..4).size = 5
83
+ row(0).column(1..4).font_style = :bold
84
+ row(-1).font_style = :bold
85
+ column(1..4).align = :right
86
+ row(-1).align = :right
87
+ end
88
+ e.draw
89
+
90
+ end
91
+ @cur -= 182
92
+ end
93
+
94
+ def operations
95
+ bounding_box([0, @cur], :width => @layout[:right]/2, :height => 180) do
96
+ stroke_bounds
97
+ move_down 5
98
+ text "16. OPERATIONS", size:10, style: :bold
99
+ stroke_horizontal_rule
100
+ rows = []
101
+ @config[:operations].each do |k,v|
102
+ rows << [v[:ques], (v[:answ].is_a?(Numeric) ? money(v[:answ]) : v[:answ])]
103
+ end
104
+ move_down(2)
105
+ indent 3,3 do
106
+ e = make_table rows,row_colors: ["F8F8F8", "FFFFFF"],:cell_style => {:padding => [3, 2, 2, 3] ,border_color:"FFFFFF",
107
+ border_widths: [0,0,0,0]},
108
+ :column_widths => [190, 60] do
109
+ column(1).align = :right
110
+ end
111
+ e.draw
112
+ end
113
+ end
114
+ end
115
+
116
+ def reconcile
117
+ bounding_box([@layout[:right]/2, @cur], :width => @layout[:right]/2, :height => 140) do
118
+ stroke_bounds
119
+ move_down 5
120
+ text "17. RECONCILIATION OF FUND BALANCES", size:10, style: :bold
121
+ stroke_horizontal_rule
122
+ move_down(2)
123
+
124
+ rows = []
125
+ rows << ['Checking Account Balance',{content:money(@config[:checking][:balance]),align: :right},nil]
126
+ rows << ['Less Outstand Checks',{content:money(@config[:checking][:outstanding]), align: :right},nil]
127
+ ab = @config[:checking][:balance] - @config[:checking][:outstanding]
128
+ save = 0
129
+ cash = 100000
130
+ t1 = ab+save+cash
131
+ bond = @balances[:savings][:ebalance]
132
+ t2 = t1 + bond
133
+ rows << [{content:'Actual Balance', align: :right, colspan: 2},{content:money(ab),align: :right}]
134
+ rows << [{content:'Savings Account Balance', align: :right, colspan: 2},{content:money(0),align: :right}]
135
+ rows << [{content:'Cash on Hand', align: :right, colspan: 2},{content:money(cash),align: :right}]
136
+ rows << [{content:'Total', align: :right, colspan: 2},{content:money(t1),align: :right}]
137
+ rows << [{content:'Bonds and Investments (cost value)', align: :right, colspan: 2},{content:money(bond),align: :right}]
138
+ rows << [{content:'Total', align: :right, colspan: 2},{content:money(t2),align: :right, text_color: (t2 != @eb ? 'FF0000' : '000000')}]
139
+ indent 2,2 do
140
+ e = make_table rows,row_colors: ["F8F8F8", "FFFFFF"],:cell_style => {:padding => [3, 2, 2, 3] ,border_color:"FFFFFF",
141
+ border_widths: [0,0,0,0]},
142
+ :column_widths => [120, 60, 60] do
143
+ row(-1).font_style = :bold
144
+ end
145
+ e.draw
146
+ end
147
+ end
148
+ @cur -= 140
149
+ end
150
+
151
+ def certify
152
+ bounding_box([@layout[:right]/2, @cur], :width => @layout[:right]/2, :height => 40) do
153
+ draw_text "18.", at:[5,30]
154
+ draw_text "TRUSTEEs' and COMMANDER's", at:[40,30], style: :bold, size:10
155
+ draw_text "CERTIFICATE OF AUDIT", at:[55,20], style: :bold, size:10
156
+ move_down 30
157
+ text "<strong>Date: <u> #{@config[:date]} </u></strong>", inline_format:true, indent_paragraphs:35
158
+ end
159
+ @cur -= 46
160
+
161
+ end
162
+
163
+ def verify
164
+ bounding_box([0, @cur], :width => @layout[:right], :height => 60) do
165
+ move_down 5
166
+ text "#{Prawn::Text::NBSP * 5}This is to certify that we (or qualified accountants) have audited the books and records of the Adjutant & Quartermaster of"+
167
+ " \n<strong><u> #{@config[:post][:post]} </u></strong> (District/County Council/Post No.)"+
168
+ " For the Fiscal Quarter ending <strong><u> #{@balances[:dates][:eoq]} </u></strong> in accordance of the National By-Laws and this Report"+
169
+ " is a true and correct statement thereof to the best of our knowledge and belief. All Vouchers and checks have been examined"+
170
+ " and found to be properly approved and checks properly signed.", inline_format:true
171
+ end
172
+ @cur -= 62
173
+
174
+ end
175
+
176
+ def quartermaster
177
+ bounding_box([0, @cur], :width => @layout[:right]/2, :height => 80) do
178
+ draw_text "Post Quartermaster:", at:[5,65], style: :bold
179
+ draw_text "Name and Address", at:[120,65], size: 6
180
+ draw_text @config[:qm][:name], at:[120,50]
181
+
182
+ draw_text @config[:qm][:address], at:[120,35]
183
+ draw_text @config[:qm][:city], at:[120,25]
184
+ end
185
+
186
+ end
187
+
188
+ def trustees
189
+ bounding_box([@layout[:right]/2, @cur], :width => @layout[:right]/2, :height => 80) do
190
+ move_down 14
191
+ text "Signed _____________________________________ Trustee"
192
+ move_down 14
193
+
194
+ text "Signed _____________________________________ Trustee"
195
+ move_down 14
196
+
197
+ text "Signed _____________________________________ Trustee"
198
+ end
199
+ @cur -= 82
200
+
201
+ end
202
+
203
+ def bonding
204
+ bounding_box([0, @cur], :width => @layout[:right], :height => 50) do
205
+ move_down 10
206
+ text "#{Prawn::Text::NBSP * 5}This is to certify that the Office of the Quartermaster is Bonded with"+
207
+ " <strong><u> #{@config[:bond][:name]} </u></strong> "+
208
+ "in the amount of <strong><u> #{'$'+money(@config[:bond][:amount])} </u></strong> until <strong><u> #{@config[:bond][:to]} </u></strong>, "+
209
+ "and that this Audit is correctly made out to the best of my knowledge and belief.", inline_format:true
210
+ end
211
+ @cur -= 52
212
+
213
+ end
214
+
215
+ def commander
216
+ bounding_box([@layout[:right]/2, @cur], :width => @layout[:right]/2, :height => 30) do
217
+ move_down 20
218
+ text "Signed _____________________________________ Commander"
219
+ end
220
+
221
+ end
222
+
223
+ def money(int)
224
+ Vfwcash.money(int)
225
+ end
226
+
227
+ end
228
+ end
@@ -0,0 +1,95 @@
1
+ class Pdf::Balance < Prawn::Document
2
+ attr_accessor :cash, :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
+ @m = Vfwcash.yyyymm(@date)
8
+ @cash = cash
9
+ cash.get_fund_balances(@date,@date.end_of_month)
10
+ @config = @cash.config
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 = %w(Fund BeginBal Debits Credits P/L EndBal)
17
+ end
18
+
19
+ def checking_row
20
+ arr = ["Checking"]
21
+ arr << {content: money(@cash.balances[:checking][:bbalance]), align: :right}
22
+ arr << {content: money(@cash.balances[:checking][:debits]), align: :right}
23
+ arr << {content: money(@cash.balances[:checking][:credits]), align: :right}
24
+ arr << {content: money(@cash.balances[:checking][:diff]), align: :right}
25
+ arr << {content: money(@cash.balances[:checking][:ebalance]), align: :right}
26
+ arr
27
+ end
28
+
29
+ def savings_row
30
+ arr = ["Savings"]
31
+ arr << {content: money(@cash.balances[:savings][:bbalance]), align: :right}
32
+ arr << {content: money(@cash.balances[:savings][:debits]), align: :right}
33
+ arr << {content: money(@cash.balances[:savings][:credits]), align: :right}
34
+ arr << {content: money(@cash.balances[:savings][:diff]), align: :right}
35
+ arr << {content: money(@cash.balances[:savings][:ebalance]), align: :right}
36
+ arr
37
+ end
38
+
39
+ def fund_rows
40
+ farr = []
41
+ @cash.checking_funds.each do |f|
42
+ arr = [f]
43
+ arr << {content: money(@cash.balances[f][:bbalance]), align: :right}
44
+ arr << {content: money(@cash.balances[f][:debits]), align: :right}
45
+ arr << {content: money(@cash.balances[f][:credits]), align: :right}
46
+ arr << {content: money(@cash.balances[f][:diff]), align: :right}
47
+ arr << {content: money(@cash.balances[f][:ebalance]), align: :right}
48
+ farr << arr
49
+ end
50
+ farr
51
+ end
52
+
53
+ def curr_assets_row
54
+ arr = ["Curr Assets"]
55
+ arr << {content: money(@cash.balances[:checking][:bbalance] + @cash.balances[:savings][:bbalance]), align: :right}
56
+ arr << {content: money(@cash.balances[:checking][:debits] + @cash.balances[:savings][:debits]), align: :right}
57
+ arr << {content: money(@cash.balances[:checking][:credits] + @cash.balances[:savings][:credits]), align: :right}
58
+ arr << {content: money(@cash.balances[:checking][:diff] + @cash.balances[:savings][:diff]), align: :right}
59
+ arr << {content: money(@cash.balances[:checking][:ebalance] + @cash.balances[:savings][:ebalance]), align: :right}
60
+ arr
61
+
62
+ end
63
+
64
+ def make_pdf
65
+ font_size 9
66
+ build_table
67
+ draw_table
68
+ end
69
+
70
+ def build_table
71
+ @rows = [header]
72
+ @rows << checking_row
73
+ @rows += fund_rows
74
+ @rows << savings_row
75
+ @rows << curr_assets_row
76
+ end
77
+
78
+ def draw_table
79
+ text "#{@config[:post][:post]} General Ledger Month Balances #{@date}", style: :bold, align: :center
80
+ move_down(2)
81
+ e = make_table @rows,row_colors: ["F8F8F8", "FFFFFF"],:cell_style => {:padding => [1, 2, 2, 1],border_color:"E0E0E0"},
82
+ :column_widths => [60,60,60,60,60,60], header:true do
83
+
84
+ row(0).font_style = :bold
85
+ row(0).align = :center
86
+ column(0).font_style = :bold
87
+ end
88
+ e.draw
89
+ end
90
+
91
+ def money(int)
92
+ Vfwcash.money(int)
93
+ end
94
+
95
+ end
@@ -0,0 +1,100 @@
1
+ class Pdf::Between < Prawn::Document
2
+ attr_accessor :cash, :date, :cwidths
3
+
4
+ def initialize(date,cash,from,to)
5
+ super( top_margin: 35, page_layout: :landscape)
6
+ @date = Vfwcash.set_date(date).beginning_of_month
7
+ @from = Vfwcash.set_date(from)
8
+ @to = Vfwcash.set_date(to)
9
+
10
+ @m = Vfwcash.yyyymm(@date)
11
+ @cash = cash
12
+ @cash.get_fund_balances(@from,@to)
13
+ @results = cash.balances
14
+ @config = @cash.config
15
+ # reset_balance
16
+ make_pdf
17
+ number_pages "#{Date.today} - Page <page> of <total>", { :start_count_at => 0, :page_filter => :all, :at => [bounds.right - 100, 0], :align => :right, :size => 6 }
18
+ end
19
+
20
+ def header
21
+ arr = %w(Fund BeginBal Debits Credits P/L EndBal)
22
+ end
23
+
24
+ def checking_row
25
+ arr = ["Checking"]
26
+ arr << {content: money(@results[:checking][:bbalance]), align: :right}
27
+ arr << {content: money(@results[:checking][:debits]), align: :right}
28
+ arr << {content: money(@results[:checking][:credits]), align: :right}
29
+ arr << {content: money(@results[:checking][:diff]), align: :right}
30
+ arr << {content: money(@results[:checking][:ebalance]), align: :right}
31
+ arr
32
+ end
33
+
34
+ def savings_row
35
+ arr = ["Savings"]
36
+ arr << {content: money(@results[:savings][:bbalance]), align: :right}
37
+ arr << {content: money(@results[:savings][:debits]), align: :right}
38
+ arr << {content: money(@results[:savings][:credits]), align: :right}
39
+ arr << {content: money(@results[:savings][:diff]), align: :right}
40
+ arr << {content: money(@results[:savings][:ebalance]), align: :right}
41
+ arr
42
+ end
43
+
44
+ def fund_rows
45
+ farr = []
46
+ @cash.checking_funds.each do |f|
47
+ arr = [f]
48
+ arr << {content: money(@results[f][:bbalance]), align: :right}
49
+ arr << {content: money(@results[f][:debits]), align: :right}
50
+ arr << {content: money(@results[f][:credits]), align: :right}
51
+ arr << {content: money(@results[f][:diff]), align: :right}
52
+ arr << {content: money(@results[f][:ebalance]), align: :right}
53
+ farr << arr
54
+ end
55
+ farr
56
+ end
57
+
58
+ def curr_assets_row
59
+ arr = ["Curr Assets"]
60
+ arr << {content: money(@results[:checking][:bbalance] + @results[:savings][:bbalance]), align: :right}
61
+ arr << {content: money(@results[:checking][:debits] + @results[:savings][:debits]), align: :right}
62
+ arr << {content: money(@results[:checking][:credits] + @results[:savings][:credits]), align: :right}
63
+ arr << {content: money(@results[:checking][:diff] + @results[:savings][:diff]), align: :right}
64
+ arr << {content: money(@results[:checking][:ebalance] + @results[:savings][:ebalance]), align: :right}
65
+ arr
66
+
67
+ end
68
+
69
+ def make_pdf
70
+ font_size 9
71
+ build_table
72
+ draw_table
73
+ end
74
+
75
+ def build_table
76
+ @rows = [header]
77
+ @rows << checking_row
78
+ @rows += fund_rows
79
+ @rows << savings_row
80
+ @rows << curr_assets_row
81
+ end
82
+
83
+ def draw_table
84
+ text "#{@config[:post][:post]} General Ledger Balances Between #{@from} and #{@to}", 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 => [60,60,60,60,60,60], header:true do
88
+
89
+ row(0).font_style = :bold
90
+ row(0).align = :center
91
+ column(0).font_style = :bold
92
+ end
93
+ e.draw
94
+ end
95
+
96
+ def money(int)
97
+ Vfwcash.money(int)
98
+ end
99
+
100
+ end
@@ -0,0 +1,69 @@
1
+
2
+ class CashAccount < SqliteBase
3
+ self.table_name = "accounts"
4
+
5
+ self.primary_key = 'guid'
6
+ has_many :splits, foreign_key: 'account_guid'
7
+ has_many :trans, through: :splits
8
+
9
+ def parent
10
+ CashAccount.find(self.parent_guid)
11
+ end
12
+
13
+ def children
14
+ CashAccount.where(parent_guid:self.guid)
15
+ end
16
+
17
+ def balance(decimal=true)
18
+ b = self.splits.sum(:value_num)
19
+ if decimal
20
+ "#{b/100}.#{b%100}"
21
+ else
22
+ b
23
+ end
24
+ end
25
+
26
+ def balance_on(date)
27
+ sp = self.splits.joins(:tran).where('transactions.post_date < ?',date.strftime('%Y%m%d')+'00')
28
+ b = sp.sum(:value_num)
29
+ end
30
+
31
+ def balances_between(first,last)
32
+ fdate = first.strftime('%Y%m%d')+'00'
33
+ ldate = last.strftime('%Y%m%d')+'24'
34
+ bb = self.balance_on(first)
35
+ sp = splits_by_month(fdate,ldate)
36
+ credits = sp.where('value_num < ?',0).sum(:value_num)
37
+ debits = sp.where('value_num >= ?', 0).sum(:value_num)
38
+ diff = debits + credits
39
+ results = {bbalance:bb,diff:diff,debits:debits,credits:credits * -1,ebalance:bb+diff}
40
+ end
41
+
42
+ def splits_by_month(bom,eom)
43
+ self.splits.joins(:tran).where('transactions.post_date between ? and ?',bom,eom)
44
+ end
45
+
46
+ def children_balance(decimal=true)
47
+ b = 0
48
+ kids = self.children
49
+ kids.each do |c|
50
+ b += c.balance(false)
51
+ end
52
+ if decimal
53
+ "#{b/100}.#{b%100}"
54
+ else
55
+ b
56
+ end
57
+ end
58
+
59
+ def account_name
60
+ account_name = self.name
61
+ p = self.parent
62
+ while p.parent_guid.present?
63
+ account_name = p.name + ":" + account_name
64
+ p = p.parent
65
+ end
66
+ return account_name
67
+ end
68
+
69
+ end