check_writer 0.0.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.
@@ -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
+