receipts 1.0.3 → 1.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +36 -0
- data/CHANGELOG.md +17 -0
- data/Gemfile +1 -1
- data/README.md +54 -0
- data/Rakefile +51 -14
- data/examples/invoice.pdf +0 -0
- data/examples/receipt.pdf +0 -0
- data/examples/statement.pdf +0 -0
- data/lib/receipts/invoice.rb +63 -97
- data/lib/receipts/receipt.rb +45 -61
- data/lib/receipts/statement.rb +88 -0
- data/lib/receipts/version.rb +1 -1
- data/lib/receipts.rb +28 -2
- data/receipts.gemspec +16 -17
- data/spec/receipts_spec.rb +3 -3
- data/spec/spec_helper.rb +2 -2
- metadata +20 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fead98b1a43ff6d6c86b13f9c8114ebcfa322b809f9f2b068b80e03370c63f65
|
4
|
+
data.tar.gz: e7e29ceceac61563c182626d3d47ab697584e67896aff884097bb955236d44ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: de764a9d7466e6680243ac5b2f033534a6140048f99eb5bc15aaad5b38d27063e4ed7e70f2d45167064dec7b3f941d34b0cab29aab1977e876c926ded6e80839
|
7
|
+
data.tar.gz: 7da1873655534b34d80bb735b8fe80da1d84d6f0618f1d1c7be35991e2d5ffeb197aa4b07390a3ba3aba4317ef42c7a874756b075213422d164ed296b9bb7a2b
|
@@ -0,0 +1,36 @@
|
|
1
|
+
name: Tests
|
2
|
+
|
3
|
+
on:
|
4
|
+
pull_request:
|
5
|
+
branches:
|
6
|
+
- '*'
|
7
|
+
push:
|
8
|
+
branches:
|
9
|
+
- master
|
10
|
+
jobs:
|
11
|
+
tests:
|
12
|
+
runs-on: ubuntu-latest
|
13
|
+
strategy:
|
14
|
+
matrix:
|
15
|
+
ruby: ['2.7', '3.0']
|
16
|
+
env:
|
17
|
+
BUNDLE_PATH_RELATIVE_TO_CWD: true
|
18
|
+
|
19
|
+
steps:
|
20
|
+
- uses: actions/checkout@master
|
21
|
+
|
22
|
+
- name: Set up Ruby
|
23
|
+
uses: ruby/setup-ruby@v1
|
24
|
+
with:
|
25
|
+
ruby-version: ${{ matrix.ruby }}
|
26
|
+
bundler: default
|
27
|
+
bundler-cache: true
|
28
|
+
|
29
|
+
- name: StandardRb check
|
30
|
+
run: bundle exec standardrb
|
31
|
+
|
32
|
+
- name: Run tests
|
33
|
+
env:
|
34
|
+
RAILS_ENV: test
|
35
|
+
run: |
|
36
|
+
bundle exec rspec
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
### Unreleased
|
2
|
+
|
3
|
+
### 1.2.0
|
4
|
+
|
5
|
+
* Update design to give more room for longer product names, addresses, etc - @excid3
|
6
|
+
|
7
|
+
### 1.1.1
|
8
|
+
|
9
|
+
* [FIX] Use `URI.parse().open` instead - @excid3 @reckerswartz
|
10
|
+
* Add I18n notes to the readme - @excid3 @reckerswartz
|
11
|
+
* Add standardrb formatting - @excid3
|
12
|
+
* Add GitHub Actions for standardrb and tests - @excid3
|
13
|
+
|
14
|
+
### 1.1.0
|
15
|
+
|
16
|
+
* [NEW] Add Statements - @anquinn
|
17
|
+
|
1
18
|
### 1.0.3
|
2
19
|
|
3
20
|
* [FIX] Fixes typo introduced in 1.0.2
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -129,6 +129,17 @@ To use an image from a URL, we recommend using `open-uri` to open the remote fil
|
|
129
129
|
|
130
130
|
If you'd like to use your own custom font, you can pass in the file paths to the `normal` and `bold` variations of your font. The bold font variation is required because it is used in the default message. If you wish to override that, you can pass in your own custom message instead.
|
131
131
|
|
132
|
+
#### Internationalization (I18n)
|
133
|
+
|
134
|
+
You can use `I18n.t` when rendering your receipts to internationalize them.
|
135
|
+
|
136
|
+
```ruby
|
137
|
+
line_items: [
|
138
|
+
[I18n.t("receipts.date"), created_at.to_s],
|
139
|
+
[I18n.t("receipts.product"), "GoRails"],
|
140
|
+
[I18n.t("receipts.transaction"), uuid]
|
141
|
+
]
|
142
|
+
```
|
132
143
|
|
133
144
|
## Rendering the Receipt PDF in your Controller
|
134
145
|
|
@@ -227,6 +238,49 @@ You can also use line_items to flexibly generate and display the table with item
|
|
227
238
|
)
|
228
239
|
```
|
229
240
|
|
241
|
+
## Statements
|
242
|
+
|
243
|
+
Statements follow the exact same set of steps as receipts, with a few minor changes and have a few extra arguments you can use:
|
244
|
+
|
245
|
+
* `issue_date` - Date the invoice was issued
|
246
|
+
|
247
|
+
* `start_date` - The start date of the statement period
|
248
|
+
|
249
|
+
* `start_date` - The end date of the statement period
|
250
|
+
|
251
|
+
* `bill_to` - A string or Array of lines with account details
|
252
|
+
|
253
|
+
You can also use line_items to flexibly generate and display the table with items in it, including subtotal, taxes, and total amount.
|
254
|
+
|
255
|
+
```ruby
|
256
|
+
Receipts::Statement.new(
|
257
|
+
id: "123",
|
258
|
+
issue_date: Date.today,
|
259
|
+
start_date: Date.today - 30,
|
260
|
+
end_date: Date.today,
|
261
|
+
bill_to: [
|
262
|
+
"GoRails, LLC",
|
263
|
+
"123 Fake Street",
|
264
|
+
"New York City, NY 10012",
|
265
|
+
nil,
|
266
|
+
"mail@example.com",
|
267
|
+
],
|
268
|
+
company: {
|
269
|
+
name: "GoRails, LLC",
|
270
|
+
address: "123 Fake Street\nNew York City, NY 10012",
|
271
|
+
email: "support@example.com",
|
272
|
+
logo: File.expand_path("./examples/gorails.png")
|
273
|
+
},
|
274
|
+
line_items: [
|
275
|
+
["<b>Item</b>", "<b>Unit Cost</b>", "<b>Quantity</b>", "<b>Amount</b>"],
|
276
|
+
["GoRails Subscription", "$19.00", "1", "$19.00"],
|
277
|
+
[nil, nil, "Subtotal", "$19.00"],
|
278
|
+
[nil, nil, "Tax Rate", "0%"],
|
279
|
+
[nil, nil, "Total", "$19.00"],
|
280
|
+
],
|
281
|
+
)
|
282
|
+
```
|
283
|
+
|
230
284
|
## Contributing
|
231
285
|
|
232
286
|
1. Fork it ( https://github.com/excid3/receipts/fork )
|
data/Rakefile
CHANGED
@@ -2,16 +2,22 @@ require "bundler/gem_tasks"
|
|
2
2
|
require "rspec/core/rake_task"
|
3
3
|
require "open-uri"
|
4
4
|
|
5
|
-
RSpec::Core::RakeTask.new(
|
5
|
+
RSpec::Core::RakeTask.new("spec")
|
6
6
|
|
7
7
|
# If you want to make this the default task
|
8
|
-
task :
|
9
|
-
task :
|
8
|
+
task default: :spec
|
9
|
+
task test: :spec
|
10
10
|
|
11
11
|
task :console do
|
12
12
|
exec "irb -r receipts -I ./lib"
|
13
13
|
end
|
14
14
|
|
15
|
+
task :examples do
|
16
|
+
[:receipt, :invoice, :statement].each { |t| Rake::Task[t].invoke }
|
17
|
+
|
18
|
+
puts "Use `open examples` to view example PDFs."
|
19
|
+
end
|
20
|
+
|
15
21
|
task :receipt do
|
16
22
|
require "./lib/receipts"
|
17
23
|
|
@@ -23,16 +29,16 @@ task :receipt do
|
|
23
29
|
name: "GoRails, LLC",
|
24
30
|
address: "123 Fake Street\nNew York City, NY 10012",
|
25
31
|
email: "support@example.com",
|
26
|
-
logo:
|
32
|
+
logo: "https://www.ruby-lang.org/images/header-ruby-logo@2x.png"
|
27
33
|
},
|
28
34
|
line_items: [
|
29
|
-
["Date",
|
35
|
+
["Date", Time.now.to_s],
|
30
36
|
["Account Billed", "Example User (user@example.com)"],
|
31
|
-
["Product",
|
32
|
-
["Amount",
|
33
|
-
["Charged to",
|
37
|
+
["Product", "GoRails"],
|
38
|
+
["Amount", "$19.00"],
|
39
|
+
["Charged to", "Visa (**** **** **** 1234)"],
|
34
40
|
["Transaction ID", "123456"]
|
35
|
-
]
|
41
|
+
]
|
36
42
|
).render_file "examples/receipt.pdf"
|
37
43
|
end
|
38
44
|
|
@@ -49,14 +55,14 @@ task :invoice do
|
|
49
55
|
"Address",
|
50
56
|
"City, State Zipcode",
|
51
57
|
nil,
|
52
|
-
"mail@example.com"
|
58
|
+
"mail@example.com"
|
53
59
|
],
|
54
60
|
company: {
|
55
61
|
name: "GoRails, LLC",
|
56
62
|
address: "123 Fake Street\nNew York City, NY 10012",
|
57
63
|
email: "support@example.com",
|
58
|
-
#logo: Rails.root.join("app/assets/images/gorails.png")
|
59
|
-
#logo: File.expand_path("./examples/gorails.png")
|
64
|
+
# logo: Rails.root.join("app/assets/images/gorails.png")
|
65
|
+
# logo: File.expand_path("./examples/gorails.png")
|
60
66
|
logo: File.open("./examples/gorails.png")
|
61
67
|
},
|
62
68
|
line_items: [
|
@@ -64,7 +70,38 @@ task :invoice do
|
|
64
70
|
["GoRails Subscription", "$19.00", "1", "$19.00"],
|
65
71
|
[nil, nil, "Subtotal", "$19.00"],
|
66
72
|
[nil, nil, "Tax Rate", "0%"],
|
67
|
-
[nil, nil, "Amount Due", "$19.00"]
|
68
|
-
]
|
73
|
+
[nil, nil, "Amount Due", "$19.00"]
|
74
|
+
]
|
69
75
|
).render_file "examples/invoice.pdf"
|
70
76
|
end
|
77
|
+
|
78
|
+
task :statement do
|
79
|
+
require "./lib/receipts"
|
80
|
+
|
81
|
+
Receipts::Statement.new(
|
82
|
+
id: "123",
|
83
|
+
issue_date: Date.today,
|
84
|
+
start_date: Date.today - 30,
|
85
|
+
end_date: Date.today,
|
86
|
+
bill_to: [
|
87
|
+
"GoRails, LLC",
|
88
|
+
"123 Fake Street",
|
89
|
+
"New York City, NY 10012",
|
90
|
+
nil,
|
91
|
+
"mail@example.com"
|
92
|
+
],
|
93
|
+
company: {
|
94
|
+
name: "GoRails, LLC",
|
95
|
+
address: "123 Fake Street\nNew York City, NY 10012",
|
96
|
+
email: "support@example.com",
|
97
|
+
logo: File.expand_path("./examples/gorails.png")
|
98
|
+
},
|
99
|
+
line_items: [
|
100
|
+
["<b>Item</b>", "<b>Unit Cost</b>", "<b>Quantity</b>", "<b>Amount</b>"],
|
101
|
+
["GoRails Subscription", "$19.00", "1", "$19.00"],
|
102
|
+
[nil, nil, "Subtotal", "$19.00"],
|
103
|
+
[nil, nil, "Tax Rate", "0%"],
|
104
|
+
[nil, nil, "Total", "$19.00"]
|
105
|
+
]
|
106
|
+
).render_file "examples/statement.pdf"
|
107
|
+
end
|
data/examples/invoice.pdf
CHANGED
Binary file
|
data/examples/receipt.pdf
CHANGED
Binary file
|
Binary file
|
data/lib/receipts/invoice.rb
CHANGED
@@ -1,24 +1,24 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "prawn"
|
2
|
+
require "prawn/table"
|
3
3
|
|
4
4
|
module Receipts
|
5
|
-
class Invoice <
|
5
|
+
class Invoice < Base
|
6
6
|
attr_reader :attributes, :id, :company, :custom_font, :line_items, :logo, :message, :product, :subheading, :bill_to, :issue_date, :due_date, :status
|
7
7
|
|
8
8
|
def initialize(attributes)
|
9
|
-
@attributes
|
10
|
-
@id
|
11
|
-
@company
|
12
|
-
@line_items
|
9
|
+
@attributes = attributes
|
10
|
+
@id = attributes.fetch(:id)
|
11
|
+
@company = attributes.fetch(:company)
|
12
|
+
@line_items = attributes.fetch(:line_items)
|
13
13
|
@custom_font = attributes.fetch(:font, {})
|
14
|
-
@message
|
15
|
-
@subheading
|
16
|
-
@bill_to
|
17
|
-
@issue_date
|
18
|
-
@due_date
|
19
|
-
@status
|
14
|
+
@message = attributes.fetch(:message) { default_message }
|
15
|
+
@subheading = attributes.fetch(:subheading) { default_subheading }
|
16
|
+
@bill_to = Array(attributes.fetch(:bill_to)).join("\n")
|
17
|
+
@issue_date = attributes.fetch(:issue_date)
|
18
|
+
@due_date = attributes.fetch(:due_date)
|
19
|
+
@status = attributes.fetch(:status)
|
20
20
|
|
21
|
-
super(
|
21
|
+
super(page_size: "LETTER")
|
22
22
|
|
23
23
|
setup_fonts if custom_font.any?
|
24
24
|
generate
|
@@ -26,100 +26,66 @@ module Receipts
|
|
26
26
|
|
27
27
|
private
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
def default_subheading
|
34
|
-
"INVOICE #%{id}"
|
35
|
-
end
|
36
|
-
|
37
|
-
def setup_fonts
|
38
|
-
font_families.update "Primary" => custom_font
|
39
|
-
font "Primary"
|
40
|
-
end
|
41
|
-
|
42
|
-
def generate
|
43
|
-
bounding_box [0, 792], width: 612, height: 792 do
|
44
|
-
bounding_box [85, 792], width: 442, height: 792 do
|
45
|
-
header
|
46
|
-
charge_details
|
47
|
-
footer
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def header
|
53
|
-
move_down 60
|
54
|
-
|
55
|
-
logo = company[:logo]
|
56
|
-
|
57
|
-
if logo.nil?
|
58
|
-
move_down 32
|
59
|
-
elsif logo.is_a?(String)
|
60
|
-
image open(logo), height: 32
|
61
|
-
else
|
62
|
-
image logo, height: 32
|
63
|
-
end
|
64
|
-
|
65
|
-
move_down 8
|
66
|
-
label (subheading % {id: id})
|
67
|
-
|
68
|
-
move_down 10
|
69
|
-
|
70
|
-
# Cache the Y value so we can have both boxes at the same height
|
71
|
-
top = y
|
72
|
-
bounding_box([0, y], width: 200) do
|
73
|
-
label "BILL TO"
|
74
|
-
|
75
|
-
move_down 5
|
76
|
-
text_box bill_to, at: [0, cursor], width: 200, height: 75, inline_format: true, size: 10, leading: 4, overflow: :shrink_to_fit
|
77
|
-
|
78
|
-
end
|
79
|
-
|
80
|
-
bounding_box([250, top], width: 200) do
|
81
|
-
label "INVOICE DATE"
|
29
|
+
def default_message
|
30
|
+
"For questions, contact us anytime at <color rgb='326d92'><link href='mailto:#{company.fetch(:email)}?subject=Charge ##{id}'><b>#{company.fetch(:email)}</b></link></color>."
|
31
|
+
end
|
82
32
|
|
83
|
-
|
84
|
-
|
33
|
+
def default_subheading
|
34
|
+
"INVOICE #%{id}"
|
35
|
+
end
|
85
36
|
|
86
|
-
|
87
|
-
|
37
|
+
def generate
|
38
|
+
header
|
39
|
+
description
|
40
|
+
invoice_details
|
41
|
+
charge_details
|
42
|
+
footer
|
43
|
+
end
|
88
44
|
|
89
|
-
|
90
|
-
|
45
|
+
def header(height: 24)
|
46
|
+
logo = company[:logo]
|
47
|
+
return if logo.nil?
|
48
|
+
image load_image(logo), height: height
|
49
|
+
end
|
91
50
|
|
92
|
-
|
93
|
-
|
51
|
+
def description
|
52
|
+
move_down 8
|
53
|
+
text label(subheading % {id: id}), inline_format: true, leading: 4
|
54
|
+
end
|
94
55
|
|
95
|
-
|
96
|
-
|
97
|
-
|
56
|
+
def invoice_details
|
57
|
+
move_down 10
|
58
|
+
font_size 9
|
59
|
+
|
60
|
+
line_items = [
|
61
|
+
[{content: "#{label("BILL TO")}\n#{bill_to}", rowspan: 3, padding: [0, 12, 0, 0]}, "#{label("INVOICE DATE")}\n#{issue_date}"],
|
62
|
+
["#{label("DUE DATE")}\n#{due_date}"],
|
63
|
+
["#{label("STATUS")}\n#{status}"]
|
64
|
+
]
|
65
|
+
table(line_items, width: bounds.width, cell_style: {inline_format: true, overflow: :shrink_to_fit}) do
|
66
|
+
cells.borders = []
|
98
67
|
end
|
68
|
+
end
|
99
69
|
|
100
|
-
|
101
|
-
|
70
|
+
def charge_details
|
71
|
+
move_down 30
|
102
72
|
|
103
|
-
|
73
|
+
borders = line_items.length - 2
|
104
74
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
end
|
75
|
+
table(line_items, width: bounds.width, cell_style: {border_color: "cccccc", inline_format: true, overflow: :shrink_to_fit}) do
|
76
|
+
cells.padding = 10
|
77
|
+
cells.borders = []
|
78
|
+
row(0..borders).borders = [:bottom]
|
110
79
|
end
|
80
|
+
end
|
111
81
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
move_down 30
|
117
|
-
text company.fetch(:name), inline_format: true
|
118
|
-
text "<color rgb='888888'>#{company.fetch(:address)}</color>", inline_format: true
|
119
|
-
end
|
82
|
+
def footer
|
83
|
+
move_down 30
|
84
|
+
text message, inline_format: true, leading: 4
|
120
85
|
|
121
|
-
|
122
|
-
|
123
|
-
|
86
|
+
move_down 30
|
87
|
+
text company.fetch(:name), inline_format: true
|
88
|
+
text "<color rgb='888888'>#{company.fetch(:address)}</color>", inline_format: true
|
89
|
+
end
|
124
90
|
end
|
125
91
|
end
|
data/lib/receipts/receipt.rb
CHANGED
@@ -1,20 +1,17 @@
|
|
1
|
-
require 'prawn'
|
2
|
-
require 'prawn/table'
|
3
|
-
|
4
1
|
module Receipts
|
5
|
-
class Receipt <
|
2
|
+
class Receipt < Base
|
6
3
|
attr_reader :attributes, :id, :company, :custom_font, :line_items, :logo, :message, :product, :subheading
|
7
4
|
|
8
5
|
def initialize(attributes)
|
9
|
-
@attributes
|
10
|
-
@id
|
11
|
-
@company
|
12
|
-
@line_items
|
6
|
+
@attributes = attributes
|
7
|
+
@id = attributes.fetch(:id)
|
8
|
+
@company = attributes.fetch(:company)
|
9
|
+
@line_items = attributes.fetch(:line_items)
|
13
10
|
@custom_font = attributes.fetch(:font, {})
|
14
|
-
@message
|
15
|
-
@subheading
|
11
|
+
@message = attributes.fetch(:message) { default_message }
|
12
|
+
@subheading = attributes.fetch(:subheading) { default_subheading }
|
16
13
|
|
17
|
-
super(
|
14
|
+
super(page_size: "LETTER")
|
18
15
|
|
19
16
|
setup_fonts if custom_font.any?
|
20
17
|
generate
|
@@ -22,65 +19,52 @@ module Receipts
|
|
22
19
|
|
23
20
|
private
|
24
21
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
def default_subheading
|
30
|
-
"RECEIPT FOR CHARGE #%{id}"
|
31
|
-
end
|
32
|
-
|
33
|
-
def setup_fonts
|
34
|
-
font_families.update "Primary" => custom_font
|
35
|
-
font "Primary"
|
36
|
-
end
|
37
|
-
|
38
|
-
def generate
|
39
|
-
bounding_box [0, 792], width: 612, height: 792 do
|
40
|
-
bounding_box [85, 792], width: 442, height: 792 do
|
41
|
-
header
|
42
|
-
charge_details
|
43
|
-
footer
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
22
|
+
def default_message
|
23
|
+
"We've received your payment for #{attributes.fetch(:product)}. You can keep this receipt for your records. For questions, contact us anytime at <color rgb='326d92'><link href='mailto:#{company.fetch(:email)}?subject=Charge ##{id}'><b>#{company.fetch(:email)}</b></link></color>."
|
24
|
+
end
|
47
25
|
|
48
|
-
|
49
|
-
|
26
|
+
def default_subheading
|
27
|
+
"RECEIPT FOR CHARGE #%{id}"
|
28
|
+
end
|
50
29
|
|
51
|
-
|
30
|
+
def generate
|
31
|
+
header
|
32
|
+
description
|
33
|
+
charge_details
|
34
|
+
footer
|
35
|
+
end
|
52
36
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
image logo, height: 32
|
59
|
-
end
|
37
|
+
def header(height: 24)
|
38
|
+
logo = company[:logo]
|
39
|
+
return if logo.nil?
|
40
|
+
image load_image(logo), height: height
|
41
|
+
end
|
60
42
|
|
61
|
-
|
62
|
-
|
43
|
+
def description
|
44
|
+
move_down 8
|
45
|
+
text "<color rgb='a6a6a6'>#{subheading % {id: id}}</color>", inline_format: true
|
63
46
|
|
64
|
-
|
65
|
-
|
66
|
-
|
47
|
+
move_down 30
|
48
|
+
text message, inline_format: true, leading: 4
|
49
|
+
end
|
67
50
|
|
68
|
-
|
69
|
-
|
51
|
+
def charge_details
|
52
|
+
move_down 30
|
53
|
+
font_size 9
|
70
54
|
|
71
|
-
|
55
|
+
borders = line_items.length - 2
|
72
56
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
end
|
57
|
+
table(line_items, width: bounds.width, cell_style: {border_color: "cccccc", inline_format: true}) do
|
58
|
+
cells.padding = 10
|
59
|
+
cells.borders = []
|
60
|
+
row(0..borders).borders = [:bottom]
|
78
61
|
end
|
62
|
+
end
|
79
63
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
64
|
+
def footer
|
65
|
+
move_down 45
|
66
|
+
text company.fetch(:name), inline_format: true
|
67
|
+
text "<color rgb='888888'>#{company.fetch(:address)}</color>", inline_format: true
|
68
|
+
end
|
85
69
|
end
|
86
70
|
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Receipts
|
2
|
+
class Statement < Base
|
3
|
+
attr_reader :attributes, :id, :company, :custom_font, :line_items, :logo, :message, :product, :subheading, :bill_to, :issue_date, :start_date, :end_date
|
4
|
+
|
5
|
+
def initialize(attributes)
|
6
|
+
@attributes = attributes
|
7
|
+
@id = attributes.fetch(:id)
|
8
|
+
@company = attributes.fetch(:company)
|
9
|
+
@line_items = attributes.fetch(:line_items)
|
10
|
+
@custom_font = attributes.fetch(:font, {})
|
11
|
+
@message = attributes.fetch(:message) { default_message }
|
12
|
+
@subheading = attributes.fetch(:subheading) { default_subheading }
|
13
|
+
@bill_to = Array(attributes.fetch(:bill_to)).join("\n")
|
14
|
+
@issue_date = attributes.fetch(:issue_date)
|
15
|
+
@start_date = attributes.fetch(:start_date)
|
16
|
+
@end_date = attributes.fetch(:end_date)
|
17
|
+
|
18
|
+
super(page_size: "LETTER")
|
19
|
+
|
20
|
+
setup_fonts if custom_font.any?
|
21
|
+
generate
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def default_message
|
27
|
+
"For questions, contact us anytime at <color rgb='326d92'><link href='mailto:#{company.fetch(:email)}?subject=Charge ##{id}'><b>#{company.fetch(:email)}</b></link></color>."
|
28
|
+
end
|
29
|
+
|
30
|
+
def default_subheading
|
31
|
+
"STATEMENT #%{id}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def generate
|
35
|
+
header
|
36
|
+
description
|
37
|
+
statement_details
|
38
|
+
charge_details
|
39
|
+
footer
|
40
|
+
end
|
41
|
+
|
42
|
+
def header(height: 24)
|
43
|
+
logo = company[:logo]
|
44
|
+
return if logo.nil?
|
45
|
+
image load_image(logo), height: height
|
46
|
+
end
|
47
|
+
|
48
|
+
def description
|
49
|
+
move_down 8
|
50
|
+
text label(subheading % {id: id}), inline_format: true, leading: 4
|
51
|
+
end
|
52
|
+
|
53
|
+
def statement_details
|
54
|
+
move_down 10
|
55
|
+
font_size 9
|
56
|
+
|
57
|
+
line_items = [
|
58
|
+
[{content: "#{label("BILL TO")}\n#{bill_to}", rowspan: 3, padding: [0, 12, 0, 0]}, "#{label("INVOICE DATE")}\n#{issue_date}"],
|
59
|
+
["#{label("STATEMENT DATE")}\n#{issue_date}"],
|
60
|
+
["#{label("STATEMENT PERIOD")}\n#{start_date} - #{end_date}"]
|
61
|
+
]
|
62
|
+
table(line_items, width: bounds.width, cell_style: {inline_format: true, overflow: :shrink_to_fit}) do
|
63
|
+
cells.borders = []
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def charge_details
|
68
|
+
move_down 30
|
69
|
+
|
70
|
+
borders = line_items.length - 2
|
71
|
+
|
72
|
+
table(line_items, width: bounds.width, cell_style: {border_color: "cccccc", inline_format: true}) do
|
73
|
+
cells.padding = 10
|
74
|
+
cells.borders = []
|
75
|
+
row(0..borders).borders = [:bottom]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def footer
|
80
|
+
move_down 30
|
81
|
+
text message, inline_format: true, leading: 4
|
82
|
+
|
83
|
+
move_down 30
|
84
|
+
text company.fetch(:name), inline_format: true
|
85
|
+
text "<color rgb='888888'>#{company.fetch(:address)}</color>", inline_format: true
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
data/lib/receipts/version.rb
CHANGED
data/lib/receipts.rb
CHANGED
@@ -1,3 +1,29 @@
|
|
1
1
|
require "receipts/version"
|
2
|
-
require "
|
3
|
-
require "
|
2
|
+
require "open-uri"
|
3
|
+
require "prawn"
|
4
|
+
require "prawn/table"
|
5
|
+
|
6
|
+
module Receipts
|
7
|
+
autoload :Invoice, "receipts/invoice"
|
8
|
+
autoload :Receipt, "receipts/receipt"
|
9
|
+
autoload :Statement, "receipts/statement"
|
10
|
+
|
11
|
+
class Base < Prawn::Document
|
12
|
+
def setup_fonts
|
13
|
+
font_families.update "Primary" => custom_font
|
14
|
+
font "Primary"
|
15
|
+
end
|
16
|
+
|
17
|
+
def load_image(logo)
|
18
|
+
if logo.is_a? String
|
19
|
+
logo.start_with?("http") ? URI.parse(logo).open : File.open(logo)
|
20
|
+
else
|
21
|
+
logo
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def label(text)
|
26
|
+
"<font size='8'><color rgb='a6a6a6'>#{text}</color></font>"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/receipts.gemspec
CHANGED
@@ -1,29 +1,28 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
3
|
+
require "receipts/version"
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name
|
8
|
-
spec.version
|
9
|
-
spec.authors
|
10
|
-
spec.email
|
11
|
-
spec.summary
|
12
|
-
spec.description
|
13
|
-
spec.homepage
|
14
|
-
spec.license
|
6
|
+
spec.name = "receipts"
|
7
|
+
spec.version = Receipts::VERSION
|
8
|
+
spec.authors = ["Chris Oliver"]
|
9
|
+
spec.email = ["excid3@gmail.com"]
|
10
|
+
spec.summary = "Receipts for your Rails application that works with any payment provider."
|
11
|
+
spec.description = "Receipts for your Rails application that works with any payment provider."
|
12
|
+
spec.homepage = ""
|
13
|
+
spec.license = "MIT"
|
15
14
|
|
16
|
-
spec.files
|
17
|
-
spec.executables
|
18
|
-
spec.test_files
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
18
|
spec.require_paths = ["lib"]
|
20
19
|
|
21
20
|
spec.add_development_dependency "bundler"
|
22
21
|
spec.add_development_dependency "rake", "~> 10.0"
|
23
22
|
spec.add_development_dependency "rspec"
|
24
23
|
spec.add_development_dependency "pry"
|
24
|
+
spec.add_development_dependency "standard"
|
25
25
|
|
26
|
-
spec.add_dependency
|
27
|
-
spec.add_dependency
|
28
|
-
spec.add_dependency 'ttfunk', '~> 1.5.1'
|
26
|
+
spec.add_dependency "prawn", ">= 1.3.0", "< 3.0.0"
|
27
|
+
spec.add_dependency "prawn-table", "~> 0.2.1"
|
29
28
|
end
|
data/spec/receipts_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Receipts do
|
4
4
|
it "lets you create a new receipt" do
|
@@ -11,8 +11,8 @@ describe Receipts do
|
|
11
11
|
email: "teachers@onemonth.com"
|
12
12
|
},
|
13
13
|
line_items: [
|
14
|
-
["Product",
|
15
|
-
]
|
14
|
+
["Product", "GoRails"]
|
15
|
+
]
|
16
16
|
).class.name).to eq("Receipts::Receipt")
|
17
17
|
end
|
18
18
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: receipts
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Oliver
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-09-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: standard
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: prawn
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -100,20 +114,6 @@ dependencies:
|
|
100
114
|
- - "~>"
|
101
115
|
- !ruby/object:Gem::Version
|
102
116
|
version: 0.2.1
|
103
|
-
- !ruby/object:Gem::Dependency
|
104
|
-
name: ttfunk
|
105
|
-
requirement: !ruby/object:Gem::Requirement
|
106
|
-
requirements:
|
107
|
-
- - "~>"
|
108
|
-
- !ruby/object:Gem::Version
|
109
|
-
version: 1.5.1
|
110
|
-
type: :runtime
|
111
|
-
prerelease: false
|
112
|
-
version_requirements: !ruby/object:Gem::Requirement
|
113
|
-
requirements:
|
114
|
-
- - "~>"
|
115
|
-
- !ruby/object:Gem::Version
|
116
|
-
version: 1.5.1
|
117
117
|
description: Receipts for your Rails application that works with any payment provider.
|
118
118
|
email:
|
119
119
|
- excid3@gmail.com
|
@@ -122,6 +122,7 @@ extensions: []
|
|
122
122
|
extra_rdoc_files: []
|
123
123
|
files:
|
124
124
|
- ".github/FUNDING.yml"
|
125
|
+
- ".github/workflows/ci.yml"
|
125
126
|
- ".gitignore"
|
126
127
|
- ".travis.yml"
|
127
128
|
- CHANGELOG.md
|
@@ -132,9 +133,11 @@ files:
|
|
132
133
|
- examples/gorails.png
|
133
134
|
- examples/invoice.pdf
|
134
135
|
- examples/receipt.pdf
|
136
|
+
- examples/statement.pdf
|
135
137
|
- lib/receipts.rb
|
136
138
|
- lib/receipts/invoice.rb
|
137
139
|
- lib/receipts/receipt.rb
|
140
|
+
- lib/receipts/statement.rb
|
138
141
|
- lib/receipts/version.rb
|
139
142
|
- receipts.gemspec
|
140
143
|
- spec/receipts_spec.rb
|
@@ -158,7 +161,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
158
161
|
- !ruby/object:Gem::Version
|
159
162
|
version: '0'
|
160
163
|
requirements: []
|
161
|
-
rubygems_version: 3.
|
164
|
+
rubygems_version: 3.2.22
|
162
165
|
signing_key:
|
163
166
|
specification_version: 4
|
164
167
|
summary: Receipts for your Rails application that works with any payment provider.
|