check_writer 0.0.0 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +25 -4
- data/VERSION +1 -1
- data/check_writer.gemspec +8 -1
- data/lib/check_writer.rb +1 -0
- data/lib/check_writer/attribute_formatting.rb +46 -0
- data/lib/check_writer/check.rb +41 -77
- data/spec/assets/test-0.12.0.pdf +0 -0
- data/spec/assets/test-0.6.1.pdf +0 -0
- data/spec/assets/test-0.6.3.pdf +0 -0
- data/spec/assets/two_in_one-0.12.0.pdf +0 -0
- data/spec/assets/two_in_one-0.6.1.pdf +0 -0
- data/spec/assets/two_in_one-0.6.3.pdf +0 -0
- data/spec/assets/with_stubs-0.12.0.pdf +0 -0
- data/spec/assets/with_stubs-0.6.1.pdf +0 -0
- data/spec/assets/with_stubs-0.6.3.pdf +0 -0
- data/spec/check_spec.rb +33 -0
- metadata +10 -3
data/README.rdoc
CHANGED
@@ -2,16 +2,26 @@
|
|
2
2
|
|
3
3
|
A ruby gem to help generate checks in PDF format.
|
4
4
|
|
5
|
+
It generates PDF checks that look something
|
6
|
+
like this[https://github.com/rylwin/check_writer/raw/master/spec/assets/test-0.12.0.pdf].
|
7
|
+
Print that PDF on check stock and you've got yourself a real check.
|
8
|
+
|
5
9
|
== Project Status
|
6
10
|
|
7
|
-
A version of this code has been used in a production application for a couple of years
|
11
|
+
A version of this code has been used in a production application for a couple of years
|
12
|
+
and we are finally getting around to extracting the check writing code. As we go through this
|
13
|
+
process, there may be significant changes to the API. You've been warned.
|
8
14
|
|
9
15
|
Currently the only check stock format that is supported is the 1/3 bottom check.
|
10
|
-
You can get some check stock at
|
16
|
+
You can get some check stock at
|
17
|
+
Amazon[http://www.amazon.com/gp/product/B002HIV1KQ/ref=as_li_qf_sp_asn_il_tl?ie=UTF8&tag=checkwriter-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=B002HIV1KQ],
|
18
|
+
amongst other places.
|
11
19
|
|
12
20
|
== GnuMICR
|
13
21
|
|
14
|
-
check_writer uses GnuMICR (http://www.sandeen.net/GnuMICR) to print the MICR numbers at the
|
22
|
+
check_writer uses GnuMICR (http://www.sandeen.net/GnuMICR) to print the MICR numbers at the
|
23
|
+
bottom of the check. Please read the notes on the GnuMICR site. We have not
|
24
|
+
had any issues using this font (2+ years now), but that is no guarantee.
|
15
25
|
|
16
26
|
== Example
|
17
27
|
|
@@ -38,7 +48,18 @@ check_writer uses GnuMICR (http://www.sandeen.net/GnuMICR) to print the MICR num
|
|
38
48
|
|
39
49
|
check.to_pdf # returns PDF file data
|
40
50
|
|
41
|
-
|
51
|
+
If you set the +with_stubs+ option to +true+ you'll get a bit of formatting
|
52
|
+
and information displayed in the top and middle check stub.
|
53
|
+
Here's an example[https://github.com/rylwin/check_writer/raw/master/spec/assets/test-0.12.0.pdf].
|
54
|
+
|
55
|
+
Instead of just returning a PDF, you can access the Prawn PDF writer object
|
56
|
+
(Prawn::Document), which you can use to further customize the check or even
|
57
|
+
include multiple checks on the same PDF:
|
58
|
+
|
59
|
+
pdf = check1.to_prawn
|
60
|
+
pdf.start_new_page # this is a prawn method
|
61
|
+
pdf = check2.to_prawn(pdf)
|
62
|
+
pdf.render # returns the PDF data for a PDF w/ two checks on two pages
|
42
63
|
|
43
64
|
== Tests
|
44
65
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.1.0
|
data/check_writer.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "check_writer"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.1.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Ryan Winograd"]
|
@@ -34,10 +34,17 @@ Gem::Specification.new do |s|
|
|
34
34
|
"gemfiles/prawn0.6.3.gemfile",
|
35
35
|
"gemfiles/prawn0.6.3.gemfile.lock",
|
36
36
|
"lib/check_writer.rb",
|
37
|
+
"lib/check_writer/attribute_formatting.rb",
|
37
38
|
"lib/check_writer/check.rb",
|
38
39
|
"spec/assets/test-0.12.0.pdf",
|
39
40
|
"spec/assets/test-0.6.1.pdf",
|
40
41
|
"spec/assets/test-0.6.3.pdf",
|
42
|
+
"spec/assets/two_in_one-0.12.0.pdf",
|
43
|
+
"spec/assets/two_in_one-0.6.1.pdf",
|
44
|
+
"spec/assets/two_in_one-0.6.3.pdf",
|
45
|
+
"spec/assets/with_stubs-0.12.0.pdf",
|
46
|
+
"spec/assets/with_stubs-0.6.1.pdf",
|
47
|
+
"spec/assets/with_stubs-0.6.3.pdf",
|
41
48
|
"spec/check_spec.rb",
|
42
49
|
"spec/spec_helper.rb",
|
43
50
|
"vendor/GnuMICR-0.30/AUTHORS",
|
data/lib/check_writer.rb
CHANGED
@@ -0,0 +1,46 @@
|
|
1
|
+
module CheckWriter
|
2
|
+
|
3
|
+
# Provides formatting methods for Check attributes
|
4
|
+
module AttributeFormatting
|
5
|
+
|
6
|
+
# Returns an integer representing the number of cents of the amount
|
7
|
+
#
|
8
|
+
# amount = 3.23 => 23
|
9
|
+
def cents
|
10
|
+
((amount.to_f - dollars) * 100).to_i
|
11
|
+
end
|
12
|
+
|
13
|
+
# Returns an integer representing the number of dollars of the amount
|
14
|
+
#
|
15
|
+
# amount = 3.23 => 3
|
16
|
+
def dollars
|
17
|
+
amount.to_i
|
18
|
+
end
|
19
|
+
|
20
|
+
# Formats the amount as currency
|
21
|
+
#
|
22
|
+
# amount = 1000 => $1,000.00
|
23
|
+
def formatted_amount
|
24
|
+
separated_dollars = dollars.to_s.gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1,")
|
25
|
+
"$#{separated_dollars}.#{cents}"
|
26
|
+
end
|
27
|
+
|
28
|
+
# Converts numeric amount of the check into words.
|
29
|
+
#
|
30
|
+
# amount = 1.12 => One Dollar and Twelve Cents
|
31
|
+
def amount_in_words
|
32
|
+
# Wrap cents in string before calling numwords to avoid
|
33
|
+
# SafeBuffer cannot modify string in place error
|
34
|
+
cents = "#{self.cents}".en.numwords
|
35
|
+
|
36
|
+
"#{dollars.en.numwords} Dollars and #{cents} Cents".titleize
|
37
|
+
end
|
38
|
+
|
39
|
+
# Formats date
|
40
|
+
def formatted_date
|
41
|
+
date.strftime('%B %e, %Y')
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
data/lib/check_writer/check.rb
CHANGED
@@ -1,53 +1,42 @@
|
|
1
1
|
module CheckWriter
|
2
2
|
|
3
|
+
# Check generates checks as a PDF
|
3
4
|
class Check
|
4
5
|
|
6
|
+
include CheckWriter::AttributeFormatting
|
7
|
+
|
5
8
|
attr_accessor :number, :date,
|
6
9
|
:payee_name, :payor_name,
|
7
10
|
:payee_address, :payor_address,
|
8
11
|
:bank_name, :bank_address, :bank_fraction,
|
9
12
|
:routing_number, :account_number,
|
10
|
-
:amount, :memo
|
13
|
+
:amount, :memo,
|
14
|
+
:with_stubs
|
11
15
|
|
12
16
|
def initialize(attributes={})
|
13
|
-
|
14
|
-
|
17
|
+
attributes.reverse_merge!(
|
18
|
+
:date => Date.today,
|
19
|
+
:with_stubs => false
|
20
|
+
)
|
15
21
|
|
16
|
-
|
17
|
-
@date||Date.today
|
22
|
+
_assign_attributes(attributes)
|
18
23
|
end
|
19
24
|
|
20
|
-
#
|
21
|
-
|
22
|
-
|
23
|
-
def cents
|
24
|
-
((amount.to_f - dollars) * 100).to_i
|
25
|
+
# Renders the check as a pdf and returns the pdf data
|
26
|
+
def to_pdf
|
27
|
+
to_prawn.render
|
25
28
|
end
|
26
29
|
|
27
|
-
#
|
30
|
+
# Renders the check and returns the Prawn::Document for
|
31
|
+
# further manipulation.
|
28
32
|
#
|
29
|
-
#
|
30
|
-
|
31
|
-
|
32
|
-
|
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)
|
33
|
+
# To use an existing Prawn::Document, pass this in as the
|
34
|
+
# +pdf+ argument. If +pdf+ is nil, a new Prawn::Document
|
35
|
+
# will be created.
|
36
|
+
def to_prawn(pdf=nil)
|
37
|
+
@pdf = pdf||Prawn::Document.new(:bottom_margin => 0.0)
|
49
38
|
_generate_check_pdf
|
50
|
-
@pdf
|
39
|
+
@pdf
|
51
40
|
end
|
52
41
|
|
53
42
|
private
|
@@ -60,8 +49,11 @@ module CheckWriter
|
|
60
49
|
|
61
50
|
def _generate_check_pdf
|
62
51
|
@pdf.move_down(between_box_height/4.0)
|
63
|
-
|
64
|
-
|
52
|
+
|
53
|
+
if with_stubs
|
54
|
+
check_stub(true) # top 1/3 stub
|
55
|
+
check_stub(false) # middle 1/3 stub
|
56
|
+
end
|
65
57
|
|
66
58
|
@pdf.bounding_box [@pdf.bounds.left,@pdf.bounds.top - extra_top_margin_height - box_height*2 - between_box_height*2],
|
67
59
|
:width => @pdf.bounds.right - @pdf.bounds.left, :height => check_box_height do
|
@@ -72,7 +64,6 @@ module CheckWriter
|
|
72
64
|
|
73
65
|
bank
|
74
66
|
payor
|
75
|
-
#property_name
|
76
67
|
date_and_amount_and_memo
|
77
68
|
_payee_address
|
78
69
|
signature
|
@@ -92,48 +83,29 @@ module CheckWriter
|
|
92
83
|
return [@pdf.bounds.left, center_y + 2], [@pdf.bounds.right, center_y + 2]
|
93
84
|
end
|
94
85
|
|
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
86
|
def box_bottom_row
|
87
|
+
# Payor and payee names
|
126
88
|
@pdf.move_to [@pdf.bounds.left, inches(0.5)]
|
127
89
|
@pdf.line_to [@pdf.bounds.right, inches(0.5)]
|
128
90
|
@pdf.bounding_box [@pdf.bounds.left + 8, inches(0.5) - 6], :width => inches(6.75) do
|
129
|
-
@pdf.text "Payor: #{
|
130
|
-
@pdf.text "Payee: #{
|
91
|
+
@pdf.text "Payor: #{payor_name}"
|
92
|
+
@pdf.text "Payee: #{payee_name}"
|
131
93
|
end
|
94
|
+
|
95
|
+
# Amount
|
96
|
+
@pdf.move_to [@pdf.bounds.right - inches(2), inches(0.5)]
|
97
|
+
@pdf.line_to [@pdf.bounds.right - inches(2), 0]
|
98
|
+
@pdf.bounding_box [@pdf.bounds.left + inches(5.5), inches(0.5) - 6], :width => inches(1), :height => inches(0.5) do
|
99
|
+
@pdf.text "Amount", :align => :center
|
100
|
+
@pdf.text formatted_amount, :align => :center
|
101
|
+
end
|
102
|
+
|
103
|
+
# Check date
|
132
104
|
@pdf.move_to [@pdf.bounds.right - inches(1), inches(0.5)]
|
133
105
|
@pdf.line_to [@pdf.bounds.right - inches(1), 0]
|
134
106
|
@pdf.bounding_box [@pdf.bounds.left + inches(6.5), inches(0.5) - 6], :width => inches(1), :height => inches(0.5) do
|
135
107
|
@pdf.text "Date", :align => :center
|
136
|
-
@pdf.text
|
108
|
+
@pdf.text formatted_date, :align => :center
|
137
109
|
end
|
138
110
|
end
|
139
111
|
|
@@ -162,15 +134,9 @@ module CheckWriter
|
|
162
134
|
end
|
163
135
|
end
|
164
136
|
|
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
137
|
def date_and_amount_and_memo
|
172
138
|
@pdf.bounding_box [@pdf.bounds.left + inches(4.5), @pdf.bounds.top - inches(1.25)], :width => inches(1) do
|
173
|
-
@pdf.text
|
139
|
+
@pdf.text formatted_date
|
174
140
|
end
|
175
141
|
@pdf.bounding_box [@pdf.bounds.right - inches(1) - 4, @pdf.bounds.top - inches(1.25)], :width => inches(1) do
|
176
142
|
@pdf.text formatted_amount, :align => :right
|
@@ -212,8 +178,6 @@ module CheckWriter
|
|
212
178
|
top = top_stub ? @pdf.bounds.top - extra_top_margin_height : @pdf.bounds.top - extra_top_margin_height - box_height - between_box_height
|
213
179
|
@pdf.bounding_box [@pdf.bounds.left, top], :width => @pdf.bounds.right - @pdf.bounds.left, :height => box_height do
|
214
180
|
@pdf.stroke_bounds
|
215
|
-
box_info_row
|
216
|
-
box_info_block if top_stub
|
217
181
|
box_bottom_row
|
218
182
|
end
|
219
183
|
end
|
data/spec/assets/test-0.12.0.pdf
CHANGED
Binary file
|
data/spec/assets/test-0.6.1.pdf
CHANGED
Binary file
|
data/spec/assets/test-0.6.3.pdf
CHANGED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/spec/check_spec.rb
CHANGED
@@ -17,6 +17,7 @@ describe "CheckWriter::Check" do
|
|
17
17
|
]
|
18
18
|
|
19
19
|
@check = CheckWriter::Check.new(
|
20
|
+
:date => Date.parse('5/7/2012'),
|
20
21
|
:number => '12345',
|
21
22
|
:payee_name => 'John Smith',
|
22
23
|
:payee_address => payee_address,
|
@@ -54,4 +55,36 @@ describe "CheckWriter::Check" do
|
|
54
55
|
assert_data_matches_file_content('test', data)
|
55
56
|
end
|
56
57
|
|
58
|
+
context "with stubs" do
|
59
|
+
before(:each) do
|
60
|
+
@check.with_stubs = true
|
61
|
+
@data = @check.to_pdf
|
62
|
+
end
|
63
|
+
|
64
|
+
it "generates a pdf with check stubs stroked and some basic info" do
|
65
|
+
# Use this line to re-write the PDF we test against
|
66
|
+
# write_content_to_file('with_stubs', @data)
|
67
|
+
|
68
|
+
assert_data_matches_file_content('with_stubs', @data)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "#to_prawn" do
|
73
|
+
it "returns a prawn object" do
|
74
|
+
@check.to_prawn.should be_a_kind_of(Prawn::Document)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "can be used to print multiple checks" do
|
78
|
+
pdf = @check.to_prawn
|
79
|
+
pdf.start_new_page
|
80
|
+
pdf = @check.to_prawn(pdf)
|
81
|
+
@data = pdf.render
|
82
|
+
|
83
|
+
# Use this line to re-write the PDF we test against
|
84
|
+
# write_content_to_file('two_in_one', @data)
|
85
|
+
|
86
|
+
assert_data_matches_file_content('two_in_one', @data)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
57
90
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: check_writer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 0.0.0
|
10
|
+
version: 0.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Ryan Winograd
|
@@ -205,10 +205,17 @@ files:
|
|
205
205
|
- gemfiles/prawn0.6.3.gemfile
|
206
206
|
- gemfiles/prawn0.6.3.gemfile.lock
|
207
207
|
- lib/check_writer.rb
|
208
|
+
- lib/check_writer/attribute_formatting.rb
|
208
209
|
- lib/check_writer/check.rb
|
209
210
|
- spec/assets/test-0.12.0.pdf
|
210
211
|
- spec/assets/test-0.6.1.pdf
|
211
212
|
- spec/assets/test-0.6.3.pdf
|
213
|
+
- spec/assets/two_in_one-0.12.0.pdf
|
214
|
+
- spec/assets/two_in_one-0.6.1.pdf
|
215
|
+
- spec/assets/two_in_one-0.6.3.pdf
|
216
|
+
- spec/assets/with_stubs-0.12.0.pdf
|
217
|
+
- spec/assets/with_stubs-0.6.1.pdf
|
218
|
+
- spec/assets/with_stubs-0.6.3.pdf
|
212
219
|
- spec/check_spec.rb
|
213
220
|
- spec/spec_helper.rb
|
214
221
|
- vendor/GnuMICR-0.30/AUTHORS
|