check_writer 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,246 @@
1
+ module CheckWriter
2
+
3
+ class Check
4
+
5
+ attr_accessor :number, :date,
6
+ :payee_name, :payor_name,
7
+ :payee_address, :payor_address,
8
+ :bank_name, :bank_address, :bank_fraction,
9
+ :routing_number, :account_number,
10
+ :amount, :memo
11
+
12
+ def initialize(attributes={})
13
+ _assign_attributes(attributes)
14
+ end
15
+
16
+ def date
17
+ @date||Date.today
18
+ end
19
+
20
+ # Returns an integer representing the number of cents of the amount
21
+ #
22
+ # amount = 3.23 => 23
23
+ def cents
24
+ ((amount.to_f - dollars) * 100).to_i
25
+ end
26
+
27
+ # Returns an integer representing the number of dollars of the amount
28
+ #
29
+ # amount = 3.23 => 3
30
+ def dollars
31
+ amount.to_i
32
+ end
33
+
34
+ def formatted_amount
35
+ separated_dollars = dollars.to_s.gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1,")
36
+ "$#{separated_dollars}.#{cents}"
37
+ end
38
+
39
+ def amount_in_words
40
+ # Wrap cents in string before calling numwords to avoid
41
+ # SafeBuffer cannot modify string in place error
42
+ cents = "#{self.cents}".en.numwords
43
+
44
+ "#{dollars.en.numwords} Dollars and #{cents} Cents".titleize
45
+ end
46
+
47
+ def to_pdf
48
+ @pdf = Prawn::Document.new(:bottom_margin => 0.0)
49
+ _generate_check_pdf
50
+ @pdf.render
51
+ end
52
+
53
+ private
54
+
55
+ def _assign_attributes(attr)
56
+ attr.each_pair do |key, value|
57
+ send("#{key}=", value)
58
+ end
59
+ end
60
+
61
+ def _generate_check_pdf
62
+ @pdf.move_down(between_box_height/4.0)
63
+ #check_stub(true)
64
+ #check_stub(false)
65
+
66
+ @pdf.bounding_box [@pdf.bounds.left,@pdf.bounds.top - extra_top_margin_height - box_height*2 - between_box_height*2],
67
+ :width => @pdf.bounds.right - @pdf.bounds.left, :height => check_box_height do
68
+
69
+ @pdf.bounding_box [@pdf.bounds.left + inches(5.5), @pdf.bounds.top - inches(0.25)], :width => inches(2) do
70
+ check_number
71
+ end
72
+
73
+ bank
74
+ payor
75
+ #property_name
76
+ date_and_amount_and_memo
77
+ _payee_address
78
+ signature
79
+ micr
80
+ end
81
+
82
+ # calling stroke here seems to flush the writer. When we don't call stroke, some lines aren't output
83
+ @pdf.stroke
84
+ end
85
+
86
+ def inches(inches)
87
+ inches * 72.0
88
+ end
89
+
90
+ def center_of_box
91
+ center_y = (@pdf.bounds.top - @pdf.bounds.bottom)/2.0
92
+ return [@pdf.bounds.left, center_y + 2], [@pdf.bounds.right, center_y + 2]
93
+ end
94
+
95
+ def info_box(title, value, width, offset = 0)
96
+ @pdf.bounding_box [@pdf.bounds.left + 8 + offset, @pdf.bounds.top - 2], :width => width - 8 do
97
+ @pdf.text title, :align => :center
98
+ @pdf.move_down 4
99
+ @pdf.text "#{value}"
100
+ @pdf.line center_of_box
101
+ end
102
+ end
103
+
104
+ def box_info_row
105
+ info_box("Property Name", @check.property.name, inches(3.25))
106
+ info_box("Apt #", @check.unit.unit_number, inches(0.75), inches(3.25))
107
+ info_box("Description", "Deposit Refund", inches(1.5), inches(4.0))
108
+ info_box("Move-Out", @check.lease.move_out_date.to_s(:mdy), inches(1), inches(5.5)) if @check.lease.move_out_date
109
+ info_box("Amount", c(@check.amount), inches(1), inches(6.5))
110
+ end
111
+
112
+ def box_info_block
113
+ @pdf.bounding_box [@pdf.bounds.left + 8, @pdf.bounds.top - inches(0.55)], :width => inches(7) do
114
+ @pdf.text "Movein Date: #{@check.lease.move_in_date.to_time.to_s(:mdy)}" if @check.lease.move_in_date
115
+ @pdf.text "Moveout Notice: #{@check.lease.move_out_notice_date.to_time.to_s(:mdy)}" if @check.lease.move_out_notice_date
116
+ @pdf.text "Lease Exp. Date: #{@check.lease.expiration_date.to_time.to_s(:mdy)}" if @check.lease.expiration_date
117
+ @pdf.text "Term: #{@check.lease.term}"
118
+ @pdf.text "Moveout Date: #{@check.lease.move_out_date.to_time.to_s(:mdy)}" if @check.lease.move_out_date
119
+ @pdf.text "Moveout Reason: #{@check.lease.move_out_reason}" if @check.lease.move_out_reason
120
+ @pdf.text "Processed By: #{@check.refund.employee}" if @check.refund.employee
121
+ @pdf.text("STOP PAYMENT ON CHECK NO. #{@check.original_check.check_number}", :align => :center) if @check.original_check.present?
122
+ end
123
+ end
124
+
125
+ def box_bottom_row
126
+ @pdf.move_to [@pdf.bounds.left, inches(0.5)]
127
+ @pdf.line_to [@pdf.bounds.right, inches(0.5)]
128
+ @pdf.bounding_box [@pdf.bounds.left + 8, inches(0.5) - 6], :width => inches(6.75) do
129
+ @pdf.text "Payor: #{@check.property}"
130
+ @pdf.text "Payee: #{@check.lease.signers.join(", ")}"
131
+ end
132
+ @pdf.move_to [@pdf.bounds.right - inches(1), inches(0.5)]
133
+ @pdf.line_to [@pdf.bounds.right - inches(1), 0]
134
+ @pdf.bounding_box [@pdf.bounds.left + inches(6.5), inches(0.5) - 6], :width => inches(1), :height => inches(0.5) do
135
+ @pdf.text "Date", :align => :center
136
+ @pdf.text "#{@check.date.to_time.to_s(:mdy) if @check.date}", :align => :center
137
+ end
138
+ end
139
+
140
+ def bank
141
+ @pdf.bounding_box [@pdf.bounds.left + inches(4), @pdf.bounds.top - inches(0.25)], :width => inches(2) do
142
+ @pdf.font_size(10) do
143
+ @pdf.text bank_name
144
+ pdf_address bank_address
145
+ @pdf.text bank_fraction
146
+ end
147
+ end
148
+ end
149
+
150
+ def pdf_address(address)
151
+ address.each do |line|
152
+ @pdf.text line
153
+ end
154
+ end
155
+
156
+ def payor
157
+ @pdf.bounding_box [@pdf.bounds.left + inches(0.5), @pdf.bounds.top - inches(0.25)], :width => inches(3.5) do
158
+ @pdf.text payor_name, :font_size => 14
159
+ @pdf.font_size(10) do
160
+ pdf_address(payor_address)
161
+ end
162
+ end
163
+ end
164
+
165
+ def property_name
166
+ @pdf.bounding_box [@pdf.bounds.left + inches(0.5), @pdf.bounds.top - inches(0.85)], :width => inches(3.5) do
167
+ @pdf.text @check.property.name, :font_size => 14
168
+ end
169
+ end
170
+
171
+ def date_and_amount_and_memo
172
+ @pdf.bounding_box [@pdf.bounds.left + inches(4.5), @pdf.bounds.top - inches(1.25)], :width => inches(1) do
173
+ @pdf.text date.strftime('%B %e, %Y')
174
+ end
175
+ @pdf.bounding_box [@pdf.bounds.right - inches(1) - 4, @pdf.bounds.top - inches(1.25)], :width => inches(1) do
176
+ @pdf.text formatted_amount, :align => :right
177
+ end
178
+ @pdf.text_box "#{amount_in_words}#{" -"*72}", :at => [@pdf.bounds.left + 4, @pdf.bounds.top - inches(1.5)], :height => inches(0.2)
179
+ @pdf.bounding_box [@pdf.bounds.right - inches(3.5), @pdf.bounds.top - inches(1.75)], :width => inches(3.5) do
180
+ @pdf.font_size(8) do
181
+ pdf_address([*memo])
182
+ end
183
+ end
184
+ end
185
+
186
+ def _payee_address
187
+ @pdf.bounding_box [@pdf.bounds.left + 4, @pdf.bounds.top - inches(1.75)], :width => inches(3.5) do
188
+ @pdf.text "TO THE ORDER OF:", :size => 8
189
+ @pdf.bounding_box [@pdf.bounds.left + inches(0.25), @pdf.bounds.top - inches(0.3)], :width => inches(3.25) do
190
+ @pdf.text payee_name
191
+ pdf_address(payee_address)
192
+ end
193
+ end
194
+ end
195
+
196
+ def signature
197
+ @pdf.bounding_box [@pdf.bounds.right - inches(2.5), @pdf.bounds.bottom + inches(0.7)], :width => inches(2.5) do
198
+ @pdf.horizontal_rule
199
+ @pdf.move_down 2
200
+ # TODO: better currency formatting
201
+ @pdf.text "NOT VALID IF OVER $#{amount}", :size => 8, :align => :center
202
+ end
203
+ end
204
+
205
+ def check_number(vert_adjust=false)
206
+ @pdf.move_down(between_box_height/2.0) if vert_adjust
207
+ @pdf.text "Check No. #{number}", :height => 12, :align => :right
208
+ end
209
+
210
+ def check_stub(top_stub=true)
211
+ check_number(!top_stub)
212
+ top = top_stub ? @pdf.bounds.top - extra_top_margin_height : @pdf.bounds.top - extra_top_margin_height - box_height - between_box_height
213
+ @pdf.bounding_box [@pdf.bounds.left, top], :width => @pdf.bounds.right - @pdf.bounds.left, :height => box_height do
214
+ @pdf.stroke_bounds
215
+ box_info_row
216
+ box_info_block if top_stub
217
+ box_bottom_row
218
+ end
219
+ end
220
+
221
+ def micr
222
+ @pdf.bounding_box [@pdf.bounds.left + inches(0.9), @pdf.bounds.bottom + 22], :width => inches(4.5) do
223
+ @pdf.font MICR_FONT do
224
+ @pdf.text "C#{number}C A#{routing_number}A #{account_number}C"
225
+ end
226
+ end
227
+ end
228
+
229
+ def box_height
230
+ 180 # 2.5in
231
+ end
232
+
233
+ def between_box_height
234
+ 54 # 3/4in
235
+ end
236
+
237
+ def extra_top_margin_height
238
+ 36 # 1/2in
239
+ end
240
+
241
+ def check_box_height
242
+ 252 #3.5in
243
+ end
244
+ end
245
+
246
+ end
@@ -0,0 +1,9 @@
1
+ require 'prawn'
2
+ require 'active_support/all'
3
+
4
+ require 'linguistics'
5
+ Linguistics::use( :en )
6
+
7
+ dir = File.dirname(__FILE__) + '/check_writer'
8
+ MICR_FONT = "#{dir}/../../vendor/GnuMICR-0.30/GnuMICR.ttf"
9
+ require "#{dir}/check"
Binary file
Binary file
Binary file
@@ -0,0 +1,57 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "CheckWriter::Check" do
4
+
5
+ before(:each) do
6
+ payee_address = [
7
+ '123 Payee St',
8
+ 'Payeesville, TX 77000'
9
+ ]
10
+ payor_address = [
11
+ '123 Payor St',
12
+ 'Payorsville, TX 77000'
13
+ ]
14
+ bank_address = [
15
+ '123 Bank St',
16
+ 'Banksville, TX 77000'
17
+ ]
18
+
19
+ @check = CheckWriter::Check.new(
20
+ :number => '12345',
21
+ :payee_name => 'John Smith',
22
+ :payee_address => payee_address,
23
+ :payor_name => 'Payor Company Name',
24
+ :payor_address => payor_address,
25
+ :bank_name => 'Bank of America',
26
+ :bank_address => bank_address,
27
+ :bank_fraction => '12-9876/1234',
28
+ :routing_number => '1234567689',
29
+ :account_number => '123456789',
30
+ :amount => '1003.23',
31
+ :memo => 'Memo: Void after 60 days'
32
+ )
33
+ end
34
+
35
+ it "knows how many dollars and cents" do
36
+ @check.dollars.should == 1003
37
+ @check.cents.should == 23
38
+ end
39
+
40
+ it "can format the amount as currency" do
41
+ @check.formatted_amount.should == "$1,003.23"
42
+ end
43
+
44
+ it "assigns the number" do
45
+ @check.number.should == '12345'
46
+ end
47
+
48
+ it "generates pdf correctly" do
49
+ data = @check.to_pdf
50
+
51
+ # Use this line to re-write the PDF we test against
52
+ # write_content_to_file('test', data)
53
+
54
+ assert_data_matches_file_content('test', data)
55
+ end
56
+
57
+ end
@@ -0,0 +1,33 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'check_writer'
5
+
6
+ # Requires supporting files with custom matchers and macros, etc,
7
+ # in ./support/ and its subdirectories.
8
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
+
10
+ RSpec.configure do |config|
11
+
12
+ end
13
+
14
+ TEST_ASSETS = File.expand_path("assets", File.dirname(__FILE__)).to_s
15
+
16
+ # Helper to provide asset path given the "base name" of the file.
17
+ # For example, if +file+ is "default_render", asset_path returns
18
+ # "/path/to/prawnto/spec/assets/default_render-#{prawn version}.pdf"
19
+ def asset_path(file)
20
+ prawn_version = Gem.loaded_specs["prawn"].version.to_s.inspect
21
+ TEST_ASSETS + "/#{file}-#{prawn_version.gsub('"','')}.pdf"
22
+ end
23
+
24
+ def assert_data_matches_file_content(file, data)
25
+ data.bytes.to_a.should == File.open(asset_path(file)).read.bytes.to_a
26
+ end
27
+
28
+ def write_content_to_file(file, content)
29
+ f = File.new(asset_path(file), 'w')
30
+ f.write content
31
+ f.close
32
+ true
33
+ end
@@ -0,0 +1,3 @@
1
+ GnuMICR was created by:
2
+
3
+ Eric Sandeen <sandeen-gnumicr@sandeen.net>
@@ -0,0 +1,26 @@
1
+
2
+ GnuMICR Changelog
3
+
4
+ December 10, 2003
5
+ 0.30 Re-generated the TTF font using pfaedit (so I can recreate)
6
+ Generated otf font file using pfaedit
7
+ Added StdVW to StemSnapV array (Thanks t1lint!)
8
+ Fixed typo IsFixedPitch -> isFixedPitch
9
+ Rebuilt pfa and pfb with t1utils v. 1.29
10
+ Removed blather about distribution w/ a commercial
11
+ application, that's not consistent w/ the GPL.
12
+ Updated contact information.
13
+
14
+ August 12, 2000
15
+ 0.22 Included a converted TTF font (also untested)
16
+
17
+ August 2, 2000
18
+ 0.21 Added Unique ID number for the font
19
+ Added some copyright information
20
+
21
+ July 2, 2000
22
+ 0.2 Recompiled fonts with 64 char lines (oops)
23
+
24
+ July 1, 2000
25
+ 0.1 First public release
26
+