check_writer 0.0.0 → 0.1.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.
- 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
|