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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +107 -0
- data/Rakefile +2 -0
- data/bin/vfwcash +5 -0
- data/lib/models/audit.rb +228 -0
- data/lib/models/balance.rb +95 -0
- data/lib/models/between.rb +100 -0
- data/lib/models/cash_account.rb +69 -0
- data/lib/models/gcash.rb +189 -0
- data/lib/models/ledger.rb +109 -0
- data/lib/models/register.rb +54 -0
- data/lib/models/split.rb +26 -0
- data/lib/models/split_ledger.rb +69 -0
- data/lib/models/sqlite_base.rb +10 -0
- data/lib/models/summary.rb +98 -0
- data/lib/models/tran.rb +12 -0
- data/lib/templates/vfw-gray.png +0 -0
- data/lib/templates/vfwcash.gnucash +0 -0
- data/lib/templates/vfwcash.yml +95 -0
- data/lib/vfwcash/api.rb +48 -0
- data/lib/vfwcash/cli.rb +195 -0
- data/lib/vfwcash/controller.rb +83 -0
- data/lib/vfwcash/version.rb +3 -0
- data/lib/vfwcash.rb +90 -0
- data/pdf_examples/audit_201507.pdf +2826 -0
- data/pdf_examples/balance_201508.pdf +2283 -0
- data/pdf_examples/controllers/checkbooks_controller.rb +99 -0
- data/pdf_examples/ledger_201504.pdf +5758 -0
- data/pdf_examples/ledger_summary.pdf +5719 -0
- data/pdf_examples/register_201508.pdf +1157 -0
- data/pdf_examples/split_201508.pdf +4930 -0
- data/pdf_examples/views/checkbooks/balance.html.slim +53 -0
- data/pdf_examples/views/checkbooks/between.html.slim +53 -0
- data/pdf_examples/views/checkbooks/index.html.slim +57 -0
- data/pdf_examples/views/checkbooks/ledger.html.slim +58 -0
- data/pdf_examples/views/checkbooks/register.html.slim +44 -0
- data/pdf_examples/views/checkbooks/split.html.slim +45 -0
- data/pdf_examples/views/checkbooks/summary.html.slim +56 -0
- data/vfwcash.gemspec +31 -0
- 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
data/Gemfile
ADDED
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
data/bin/vfwcash
ADDED
data/lib/models/audit.rb
ADDED
@@ -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
|