receipts 1.0.4 → 2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -0
- data/Gemfile +6 -1
- data/README.md +198 -140
- data/Rakefile +91 -35
- data/examples/{gorails.png → images/logo.png} +0 -0
- data/examples/images/options.jpg +0 -0
- data/examples/invoice.pdf +0 -0
- data/examples/receipt.pdf +0 -0
- data/examples/statement.pdf +0 -0
- data/lib/receipts/base.rb +102 -0
- data/lib/receipts/invoice.rb +2 -122
- data/lib/receipts/receipt.rb +2 -83
- data/lib/receipts/statement.rb +5 -0
- data/lib/receipts/version.rb +1 -1
- data/lib/receipts.rb +10 -2
- data/receipts.gemspec +27 -22
- metadata +18 -74
- data/.github/FUNDING.yml +0 -12
- data/.gitignore +0 -15
- data/.travis.yml +0 -4
- data/spec/receipts_spec.rb +0 -18
- data/spec/spec_helper.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 875a1ff6a3a1dcca7a1de7c21362ce0837426c3f5b3299cd9f15f38daf97cfa2
|
4
|
+
data.tar.gz: 2aed77f22588a1675b558eccbe1122cc94912e04fa692aacaa7a40b16429495e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f54fc0957bccf87ebd1ae377d275f9dfe0f39a8b2cd0e8c4b5a96635183abd24f229eea142631a98d5a61156fc87cd366864e35a044a53e60ec072de08ada3e5
|
7
|
+
data.tar.gz: 87745a1fe2f9cb84c69a00d816e254c4cc7b2dfee02457ece89d9e543a39b65813bfd427e7fa789e5a56feea1a3837ac3e8cc5d4574e4894805b535de76cf630
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,26 @@
|
|
1
|
+
### Unreleased
|
2
|
+
|
3
|
+
### 2.0.0
|
4
|
+
|
5
|
+
* New, consistent layouts between Receipts, Invoices, and Statements - @excid3
|
6
|
+
* PDFs can now be completely customized - @excid3
|
7
|
+
* Add line_items to Receipts - @excid3
|
8
|
+
|
9
|
+
### 1.2.0
|
10
|
+
|
11
|
+
* Update design to give more room for longer product names, addresses, etc - @excid3
|
12
|
+
|
13
|
+
### 1.1.1
|
14
|
+
|
15
|
+
* [FIX] Use `URI.parse().open` instead - @excid3 @reckerswartz
|
16
|
+
* Add I18n notes to the readme - @excid3 @reckerswartz
|
17
|
+
* Add standardrb formatting - @excid3
|
18
|
+
* Add GitHub Actions for standardrb and tests - @excid3
|
19
|
+
|
20
|
+
### 1.1.0
|
21
|
+
|
22
|
+
* [NEW] Add Statements - @anquinn
|
23
|
+
|
1
24
|
### 1.0.3
|
2
25
|
|
3
26
|
* [FIX] Fixes typo introduced in 1.0.2
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|

|
2
2
|
|
3
|
-
# Receipts
|
3
|
+
# Receipts Gem
|
4
4
|
|
5
|
-
Receipts for your Rails application that works with any payment provider.
|
5
|
+
Receipts, Invoices, and Statements for your Rails application that works with any payment provider. Receipts uses Prawn to generate the PDFs.
|
6
6
|
|
7
|
-
Check out the [example
|
7
|
+
Check out the [example PDFs](https://github.com/excid3/receipts/blob/master/examples/).
|
8
8
|
|
9
9
|
## Installation
|
10
10
|
|
@@ -24,127 +24,157 @@ Or install it yourself as:
|
|
24
24
|
|
25
25
|
## Usage
|
26
26
|
|
27
|
-
|
28
|
-
model that stores your transaction details. In this example our
|
29
|
-
application has a model named `Charge` that we will use.
|
30
|
-
|
31
|
-
We're going to add a method called `receipt` on our model called `Charge`
|
32
|
-
that will create a new receipt for the charge using attributes from the
|
33
|
-
model.
|
34
|
-
|
35
|
-
Video Tutorial:
|
36
|
-
[GoRails Episode #51](https://gorails.com/episodes/pdf-receipts)
|
27
|
+
To generate a Receipt, Invoice, or Statement, create an instance and provide content to render:
|
37
28
|
|
38
29
|
```ruby
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
["Amount", "$#{amount / 100}.00"],
|
76
|
-
["Charged to", "#{card_type} (**** **** **** #{card_last4})"],
|
77
|
-
["Transaction ID", uuid]
|
78
|
-
],
|
79
|
-
font: {
|
80
|
-
bold: Rails.root.join('app/assets/fonts/tradegothic/TradeGothic-Bold.ttf'),
|
81
|
-
normal: Rails.root.join('app/assets/fonts/tradegothic/TradeGothic.ttf'),
|
82
|
-
}
|
83
|
-
)
|
84
|
-
end
|
85
|
-
end
|
30
|
+
r = Receipts::Receipt.new(
|
31
|
+
details: [
|
32
|
+
["Receipt Number", "123"],
|
33
|
+
["Date paid", Date.today],
|
34
|
+
["Payment method", "ACH super long super long super long super long super long"]
|
35
|
+
],
|
36
|
+
company: {
|
37
|
+
name: "Example, LLC",
|
38
|
+
address: "123 Fake Street\nNew York City, NY 10012",
|
39
|
+
email: "support@example.com",
|
40
|
+
logo: File.expand_path("./examples/images/logo.png")
|
41
|
+
},
|
42
|
+
recipient: [
|
43
|
+
"Customer",
|
44
|
+
"Their Address",
|
45
|
+
"City, State Zipcode",
|
46
|
+
nil,
|
47
|
+
"customer@example.org"
|
48
|
+
],
|
49
|
+
line_items: [
|
50
|
+
["<b>Item</b>", "<b>Unit Cost</b>", "<b>Quantity</b>", "<b>Amount</b>"],
|
51
|
+
["Subscription", "$19.00", "1", "$19.00"],
|
52
|
+
[nil, nil, "Subtotal", "$19.00"],
|
53
|
+
[nil, nil, "Tax", "$1.12"],
|
54
|
+
[nil, nil, "Total", "$20.12"],
|
55
|
+
[nil, nil, "<b>Amount paid</b>", "$20.12"],
|
56
|
+
[nil, nil, "Refunded on #{Date.today}", "$5.00"]
|
57
|
+
],
|
58
|
+
footer: "Thanks for your business. Please contact us if you have any questions."
|
59
|
+
)
|
60
|
+
|
61
|
+
# Returns a string of the raw PDF
|
62
|
+
r.render
|
63
|
+
|
64
|
+
# Writes the PDF to disk
|
65
|
+
r.render_file "examples/receipt.pdf"
|
86
66
|
```
|
87
67
|
|
88
|
-
|
89
|
-
|
68
|
+
### Options
|
69
|
+
|
70
|
+
You can pass the following options to generate a PDF:
|
71
|
+
|
72
|
+
* `recipient` - Array of customer details to include. Typically, this is name, address, email, VAT ID, etc.
|
73
|
+
|
74
|
+
* `company` - Hash of your company details
|
75
|
+
|
76
|
+
* `name` - Company name
|
77
|
+
|
78
|
+
* `address` - Company address
|
79
|
+
|
80
|
+
* `email` - Company support email address
|
90
81
|
|
91
|
-
|
82
|
+
* `phone` - Company phone number - _Optional_
|
92
83
|
|
93
|
-
* `
|
84
|
+
* `logo` - Logo to be displayed on the receipt - _Optional_
|
85
|
+
This can be either a Path, File, StringIO, or URL. Here are a few examples:
|
94
86
|
|
95
|
-
|
87
|
+
```ruby
|
88
|
+
logo: Rails.root.join("app/assets/images/logo.png")
|
89
|
+
logo: File.expand_path("./logo.png")
|
90
|
+
logo: File.open("app/assets/images/logo.png", "rb")
|
91
|
+
logo: "https://www.ruby-lang.org/images/header-ruby-logo@2x.png" # Downloaded with OpenURI
|
92
|
+
```
|
96
93
|
|
97
|
-
* `
|
94
|
+
* `details` - Array of details about the Receipt, Invoice, Statement. Typically, this is receipt numbers, issue date, due date, status, etc.
|
98
95
|
|
99
|
-
|
96
|
+
* `line_items` - Array of line items to be displayed in table format.
|
100
97
|
|
101
|
-
* `
|
98
|
+
* `footer` - String for a message at the bottom of the PDF.
|
102
99
|
|
103
|
-
|
100
|
+
* `font` - Hash of paths to font files - _Optional_
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
font: {
|
104
|
+
bold: Rails.root.join('app/assets/fonts/tradegothic/TradeGothic-Bold.ttf'),
|
105
|
+
normal: Rails.root.join('app/assets/fonts/tradegothic/TradeGothic.ttf'),
|
106
|
+
}
|
107
|
+
```
|
108
|
+
|
109
|
+
Here's an example of where each option is displayed.
|
110
|
+
|
111
|
+

|
112
|
+
|
113
|
+
### Formatting
|
114
|
+
|
115
|
+
`details` and `line_items` allow inline formatting with Prawn. This allows you to use HTML tags to format text: `<b>` `<i>` `<u>` `<strikethrough>` `<sub>` `<sup>` `<font>` `<color>` `<link>`
|
116
|
+
|
117
|
+
See [the Prawn docs](https://prawnpdf.org/api-docs/2.3.0/Prawn/Text.html#text-instance_method) for more information.
|
118
|
+
|
119
|
+
### Internationalization (I18n)
|
120
|
+
|
121
|
+
You can use `I18n.t` when rendering your receipts to internationalize them.
|
122
|
+
|
123
|
+
```ruby
|
124
|
+
line_items: [
|
125
|
+
[I18n.t("receipts.date"), created_at.to_s],
|
126
|
+
[I18n.t("receipts.product"), "GoRails"],
|
127
|
+
[I18n.t("receipts.transaction"), uuid]
|
128
|
+
]
|
129
|
+
```
|
104
130
|
|
105
|
-
|
106
|
-
* `address` - **Required**
|
107
|
-
* `email` - **Required**
|
108
|
-
* `line_items` - **Required**
|
131
|
+
### Custom PDF Content
|
109
132
|
|
110
|
-
You can
|
133
|
+
You can change the entire PDF content by instantiating an Receipts object without any options.
|
111
134
|
|
112
|
-
|
135
|
+
```ruby
|
136
|
+
receipt = Receipts::Receipt.new # creates an empty PDF
|
137
|
+
```
|
113
138
|
|
114
|
-
|
139
|
+
Each Receipts object inherits from Prawn::Document. This allows you to choose what is rendered and include any custom Prawn content you like.
|
115
140
|
|
116
141
|
```ruby
|
117
|
-
|
118
|
-
# or
|
119
|
-
logo: File.open("app/assets/images/logo.png", "rb")
|
142
|
+
receipt.text("hello world")
|
120
143
|
```
|
121
144
|
|
122
|
-
|
145
|
+
You can also use the Receipts helpers in your custom PDFs at the current cursor position.
|
146
|
+
|
147
|
+
```ruby
|
148
|
+
receipt.text("Custom header")
|
149
|
+
receipt.render_line_items([
|
150
|
+
["my line items"]
|
151
|
+
])
|
152
|
+
receipt.render_footer("This is a custom footer using the Receipts helper")
|
153
|
+
```
|
123
154
|
|
124
|
-
|
155
|
+
### Rendering PDFs
|
125
156
|
|
126
|
-
`
|
157
|
+
To render a PDF in memory, use `render`. This is recommended for serving PDFs in your Rails controllers.
|
127
158
|
|
128
|
-
|
159
|
+
```ruby
|
160
|
+
receipt.render
|
161
|
+
```
|
129
162
|
|
130
|
-
|
163
|
+
To render a PDF to disk, use `render_file`:
|
131
164
|
|
165
|
+
```ruby
|
166
|
+
receipt.render_file "receipt.pdf"
|
167
|
+
```
|
132
168
|
|
133
|
-
## Rendering
|
169
|
+
## Rendering PDFs in Rails controller actions
|
134
170
|
|
135
|
-
Here
|
136
|
-
you visit it with the PDF format, it calls the `receipt` method that we
|
137
|
-
just created on the `Charge` model.
|
171
|
+
Here's an example Rails controller action you can use for serving PDFs. We'll first look up the database record for the `Charge` we want to render a receipt for.
|
138
172
|
|
139
|
-
|
140
|
-
customize the filename to your liking.
|
173
|
+
The `Charge` model has a `receipt` method that returns a `Receipts::Receipt` instance with all the receipt data filled out.
|
141
174
|
|
142
|
-
|
175
|
+
Then we can `render` to generate the PDF in memory. This produces a String with the raw PDF data in it.
|
143
176
|
|
144
|
-
|
145
|
-
render the PDF in the browser without forcing the download. If you
|
146
|
-
delete this option or change it to `:attachment` then the receipt will
|
147
|
-
be downloaded instead.
|
177
|
+
Using `send_data` from Rails, we can send the PDF contents and provide the browser with a recommended filename, content type and disposition.
|
148
178
|
|
149
179
|
```ruby
|
150
180
|
class ChargesController < ApplicationController
|
@@ -153,12 +183,7 @@ class ChargesController < ApplicationController
|
|
153
183
|
|
154
184
|
def show
|
155
185
|
respond_to do |format|
|
156
|
-
format.pdf {
|
157
|
-
send_data @charge.receipt.render,
|
158
|
-
filename: "#{@charge.created_at.strftime("%Y-%m-%d")}-gorails-receipt.pdf",
|
159
|
-
type: "application/pdf",
|
160
|
-
disposition: :inline
|
161
|
-
}
|
186
|
+
format.pdf { send_pdf }
|
162
187
|
end
|
163
188
|
end
|
164
189
|
|
@@ -167,13 +192,18 @@ class ChargesController < ApplicationController
|
|
167
192
|
def set_charge
|
168
193
|
@charge = current_user.charges.find(params[:id])
|
169
194
|
end
|
195
|
+
|
196
|
+
def send_pdf
|
197
|
+
# Render the PDF in memory and send as the response
|
198
|
+
send_data @charge.receipt.render,
|
199
|
+
filename: "#{@charge.created_at.strftime("%Y-%m-%d")}-gorails-receipt.pdf",
|
200
|
+
type: "application/pdf",
|
201
|
+
disposition: :inline # or :attachment to download
|
202
|
+
end
|
170
203
|
end
|
171
204
|
```
|
172
205
|
|
173
|
-
|
174
|
-
`pdf` and you're good to go.
|
175
|
-
|
176
|
-
For example:
|
206
|
+
Then, just `link_to` to your charge with the format of `pdf`. For example:
|
177
207
|
|
178
208
|
```ruby
|
179
209
|
# config/routes.rb
|
@@ -181,50 +211,78 @@ resources :charges
|
|
181
211
|
```
|
182
212
|
|
183
213
|
```erb
|
184
|
-
<%= link_to "
|
214
|
+
<%= link_to "View Receipt", charge_path(@charge, format: :pdf) %>
|
185
215
|
```
|
186
216
|
|
187
217
|
## Invoices
|
188
218
|
|
189
|
-
Invoices follow the exact same set of steps as above
|
190
|
-
|
191
|
-
* `issue_date` - Date the invoice was issued
|
192
|
-
|
193
|
-
* `due_date` - Date the invoice payment is due
|
219
|
+
Invoices follow the exact same set of steps as above. You'll simply want to modify the `details` to include other information for the Invoice such as the Issue Date, Due Date, etc.
|
194
220
|
|
195
|
-
|
221
|
+
```ruby
|
222
|
+
Receipts::Invoice.new(
|
223
|
+
details: [
|
224
|
+
["Invoice Number", "123"],
|
225
|
+
["Issue Date", Date.today.strftime("%B %d, %Y")],
|
226
|
+
["Due Date", Date.today.strftime("%B %d, %Y")],
|
227
|
+
["Status", "<b><color rgb='#5eba7d'>PAID</color></b>"]
|
228
|
+
],
|
229
|
+
recipient: [
|
230
|
+
"<b>Bill To</b>",
|
231
|
+
"Customer",
|
232
|
+
"Address",
|
233
|
+
"City, State Zipcode",
|
234
|
+
"customer@example.org"
|
235
|
+
],
|
236
|
+
company: {
|
237
|
+
name: "Example, LLC",
|
238
|
+
address: "123 Fake Street\nNew York City, NY 10012",
|
239
|
+
phone: "(555) 867-5309",
|
240
|
+
email: "support@example.com",
|
241
|
+
logo: File.expand_path("./examples/images/logo.png")
|
242
|
+
},
|
243
|
+
line_items: [
|
244
|
+
["<b>Item</b>", "<b>Unit Cost</b>", "<b>Quantity</b>", "<b>Amount</b>"],
|
245
|
+
["Subscription", "$19.00", "1", "$19.00"],
|
246
|
+
[nil, nil, "Subtotal", "$19.00"],
|
247
|
+
[nil, nil, "Tax Rate", "0%"],
|
248
|
+
[nil, nil, "Amount Due", "$19.00"]
|
249
|
+
]
|
250
|
+
)
|
251
|
+
```
|
196
252
|
|
197
|
-
|
253
|
+
## Statements
|
198
254
|
|
199
|
-
You
|
255
|
+
Statements follow the exact same set of steps as above. You'll simply want to modify the `details` to include other information for the Invoice such as the Issue Date, Start and End Dates, etc.
|
200
256
|
|
201
257
|
```ruby
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
],
|
227
|
-
|
258
|
+
Receipts::Statement.new(
|
259
|
+
details: [
|
260
|
+
["Statement Number", "123"],
|
261
|
+
["Issue Date", Date.today.strftime("%B %d, %Y")],
|
262
|
+
["Period", "#{(Date.today - 30).strftime("%B %d, %Y")} - #{Date.today.strftime("%B %d, %Y")}"]
|
263
|
+
],
|
264
|
+
recipient: [
|
265
|
+
"<b>Bill To</b>",
|
266
|
+
"Customer",
|
267
|
+
"Address",
|
268
|
+
"City, State Zipcode",
|
269
|
+
"customer@example.org"
|
270
|
+
],
|
271
|
+
company: {
|
272
|
+
name: "Example, LLC",
|
273
|
+
address: "123 Fake Street\nNew York City, NY 10012",
|
274
|
+
email: "support@example.com",
|
275
|
+
phone: "(555) 867-5309",
|
276
|
+
logo: File.expand_path("./examples/images/logo.png")
|
277
|
+
},
|
278
|
+
line_items: [
|
279
|
+
["<b>Item</b>", "<b>Unit Cost</b>", "<b>Quantity</b>", "<b>Amount</b>"],
|
280
|
+
["Subscription", "$19.00", "1", "$19.00"],
|
281
|
+
[nil, nil, "Subtotal", "$19.00"],
|
282
|
+
[nil, nil, "Tax Rate", "0%"],
|
283
|
+
[nil, nil, "Total", "$19.00"]
|
284
|
+
]
|
285
|
+
)
|
228
286
|
```
|
229
287
|
|
230
288
|
## Contributing
|
data/Rakefile
CHANGED
@@ -1,70 +1,126 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "bundler/gem_tasks"
|
2
|
-
require "
|
3
|
-
require "open-uri"
|
4
|
+
require "rake/testtask"
|
4
5
|
|
5
|
-
|
6
|
+
Rake::TestTask.new(:test) do |t|
|
7
|
+
t.libs << "test"
|
8
|
+
t.libs << "lib"
|
9
|
+
t.test_files = FileList["test/**/test_*.rb"]
|
10
|
+
end
|
6
11
|
|
7
|
-
|
8
|
-
task :default => :spec
|
9
|
-
task :test => :spec
|
12
|
+
task default: :test
|
10
13
|
|
11
14
|
task :console do
|
12
15
|
exec "irb -r receipts -I ./lib"
|
13
16
|
end
|
14
17
|
|
18
|
+
task :examples do
|
19
|
+
[:receipt, :invoice, :statement].each { |t| Rake::Task[t].invoke }
|
20
|
+
puts "Use `open examples` to view example PDFs."
|
21
|
+
end
|
22
|
+
|
15
23
|
task :receipt do
|
16
24
|
require "./lib/receipts"
|
17
25
|
|
18
|
-
Receipts::Receipt.new(
|
19
|
-
|
20
|
-
|
21
|
-
|
26
|
+
r = Receipts::Receipt.new(
|
27
|
+
recipient: [
|
28
|
+
"<b>Bill To</b>",
|
29
|
+
"Customer",
|
30
|
+
"Address",
|
31
|
+
"City, State Zipcode",
|
32
|
+
"customer@example.org"
|
33
|
+
],
|
22
34
|
company: {
|
23
|
-
name: "
|
35
|
+
name: "Example, LLC",
|
24
36
|
address: "123 Fake Street\nNew York City, NY 10012",
|
37
|
+
phone: "(555) 867-5309",
|
25
38
|
email: "support@example.com",
|
26
|
-
logo:
|
39
|
+
logo: File.expand_path("./examples/images/logo.png")
|
27
40
|
},
|
28
|
-
|
29
|
-
["
|
30
|
-
["
|
31
|
-
["
|
32
|
-
["Amount", "$19.00"],
|
33
|
-
["Charged to", "Visa (**** **** **** 1234)"],
|
34
|
-
["Transaction ID", "123456"]
|
41
|
+
details: [
|
42
|
+
["Receipt Number", "123"],
|
43
|
+
["Date paid", Date.today.strftime("%B %d, %Y")],
|
44
|
+
["Payment method", "ACH super long super long super long super long super long"]
|
35
45
|
],
|
36
|
-
|
46
|
+
line_items: [
|
47
|
+
["<b>Item</b>", "<b>Unit Cost</b>", "<b>Quantity</b>", "<b>Amount</b>"],
|
48
|
+
["Subscription", "$19.00", "1", "$19.00"],
|
49
|
+
[nil, nil, "Subtotal", "$19.00"],
|
50
|
+
[nil, nil, "Tax", "$1.12"],
|
51
|
+
[nil, nil, "Total", "$20.12"],
|
52
|
+
[nil, nil, "<b>Amount paid</b>", "$20.12"],
|
53
|
+
[nil, nil, "Refunded on #{Date.today.strftime("%B %d, %Y")}", "$5.00"]
|
54
|
+
]
|
55
|
+
)
|
56
|
+
r.render_file "examples/receipt.pdf"
|
37
57
|
end
|
38
58
|
|
39
59
|
task :invoice do
|
40
60
|
require "./lib/receipts"
|
41
61
|
|
42
62
|
Receipts::Invoice.new(
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
63
|
+
details: [
|
64
|
+
["Invoice Number", "123"],
|
65
|
+
["Issue Date", Date.today.strftime("%B %d, %Y")],
|
66
|
+
["Due Date", Date.today.strftime("%B %d, %Y")],
|
67
|
+
["Status", "<b><color rgb='#5eba7d'>PAID</color></b>"]
|
68
|
+
],
|
69
|
+
recipient: [
|
70
|
+
"<b>Bill To</b>",
|
71
|
+
"Customer",
|
49
72
|
"Address",
|
50
73
|
"City, State Zipcode",
|
51
|
-
|
52
|
-
"mail@example.com",
|
74
|
+
"customer@example.org"
|
53
75
|
],
|
54
76
|
company: {
|
55
|
-
name: "
|
77
|
+
name: "Example, LLC",
|
56
78
|
address: "123 Fake Street\nNew York City, NY 10012",
|
79
|
+
phone: "(555) 867-5309",
|
57
80
|
email: "support@example.com",
|
58
|
-
#logo: Rails.root.join("app/assets/images/
|
59
|
-
#logo: File.
|
60
|
-
logo: File.
|
81
|
+
# logo: Rails.root.join("app/assets/images/logo.png")
|
82
|
+
# logo: File.open("./examples/images/logo.png")
|
83
|
+
logo: File.expand_path("./examples/images/logo.png")
|
61
84
|
},
|
62
85
|
line_items: [
|
63
86
|
["<b>Item</b>", "<b>Unit Cost</b>", "<b>Quantity</b>", "<b>Amount</b>"],
|
64
|
-
["
|
87
|
+
["Subscription", "$19.00", "1", "$19.00"],
|
65
88
|
[nil, nil, "Subtotal", "$19.00"],
|
66
89
|
[nil, nil, "Tax Rate", "0%"],
|
67
|
-
[nil, nil, "Amount Due", "$19.00"]
|
68
|
-
]
|
90
|
+
[nil, nil, "Amount Due", "$19.00"]
|
91
|
+
]
|
69
92
|
).render_file "examples/invoice.pdf"
|
70
93
|
end
|
94
|
+
|
95
|
+
task :statement do
|
96
|
+
require "./lib/receipts"
|
97
|
+
|
98
|
+
Receipts::Statement.new(
|
99
|
+
details: [
|
100
|
+
["Statement Number", "123"],
|
101
|
+
["Issue Date", Date.today.strftime("%B %d, %Y")],
|
102
|
+
["Period", "#{(Date.today - 30).strftime("%B %d, %Y")} - #{Date.today.strftime("%B %d, %Y")}"]
|
103
|
+
],
|
104
|
+
recipient: [
|
105
|
+
"<b>Bill To</b>",
|
106
|
+
"Customer",
|
107
|
+
"Address",
|
108
|
+
"City, State Zipcode",
|
109
|
+
"customer@example.org"
|
110
|
+
],
|
111
|
+
company: {
|
112
|
+
name: "Example, LLC",
|
113
|
+
address: "123 Fake Street\nNew York City, NY 10012",
|
114
|
+
email: "support@example.com",
|
115
|
+
phone: "(555) 867-5309",
|
116
|
+
logo: File.expand_path("./examples/images/logo.png")
|
117
|
+
},
|
118
|
+
line_items: [
|
119
|
+
["<b>Item</b>", "<b>Unit Cost</b>", "<b>Quantity</b>", "<b>Amount</b>"],
|
120
|
+
["Subscription", "$19.00", "1", "$19.00"],
|
121
|
+
[nil, nil, "Subtotal", "$19.00"],
|
122
|
+
[nil, nil, "Tax Rate", "0%"],
|
123
|
+
[nil, nil, "Total", "$19.00"]
|
124
|
+
]
|
125
|
+
).render_file "examples/statement.pdf"
|
126
|
+
end
|
File without changes
|
Binary file
|
data/examples/invoice.pdf
CHANGED
Binary file
|
data/examples/receipt.pdf
CHANGED
Binary file
|
Binary file
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module Receipts
|
2
|
+
class Base < Prawn::Document
|
3
|
+
attr_accessor :title, :company
|
4
|
+
|
5
|
+
class << self
|
6
|
+
attr_reader :title
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(attributes = {})
|
10
|
+
super(page_size: "LETTER")
|
11
|
+
setup_fonts attributes[:font]
|
12
|
+
|
13
|
+
@title = attributes.fetch(:title, self.class.title)
|
14
|
+
|
15
|
+
generate_from(attributes)
|
16
|
+
end
|
17
|
+
|
18
|
+
def generate_from(attributes)
|
19
|
+
return if attributes.empty?
|
20
|
+
|
21
|
+
company = attributes.fetch(:company)
|
22
|
+
header company: company
|
23
|
+
render_details attributes.fetch(:details)
|
24
|
+
render_billing_details company: company, recipient: attributes.fetch(:recipient)
|
25
|
+
render_line_items attributes.fetch(:line_items)
|
26
|
+
render_footer attributes.fetch(:footer, default_message(company: company))
|
27
|
+
end
|
28
|
+
|
29
|
+
def setup_fonts(custom_font = nil)
|
30
|
+
if !!custom_font
|
31
|
+
font_families.update "Primary" => custom_font
|
32
|
+
font "Primary"
|
33
|
+
end
|
34
|
+
|
35
|
+
font_size 8
|
36
|
+
end
|
37
|
+
|
38
|
+
def load_image(logo)
|
39
|
+
if logo.is_a? String
|
40
|
+
logo.start_with?("http") ? URI.parse(logo).open : File.open(logo)
|
41
|
+
else
|
42
|
+
logo
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def header(company: {}, height: 16)
|
47
|
+
logo = company[:logo]
|
48
|
+
|
49
|
+
if logo.nil?
|
50
|
+
text company.fetch(:name), align: :right, style: :bold, size: 16, color: "4b5563"
|
51
|
+
else
|
52
|
+
image load_image(logo), height: height, position: :right
|
53
|
+
end
|
54
|
+
|
55
|
+
move_up height
|
56
|
+
text title, style: :bold, size: 16
|
57
|
+
end
|
58
|
+
|
59
|
+
def render_details(details, margin_top: 16)
|
60
|
+
move_down margin_top
|
61
|
+
table(details, cell_style: {borders: [], inline_format: true, padding: [0, 8, 2, 0]})
|
62
|
+
end
|
63
|
+
|
64
|
+
def render_billing_details(company:, recipient:, margin_top: 16)
|
65
|
+
move_down margin_top
|
66
|
+
|
67
|
+
company_details = [
|
68
|
+
company[:address],
|
69
|
+
company[:phone],
|
70
|
+
company[:email]
|
71
|
+
].compact.join("\n")
|
72
|
+
|
73
|
+
line_items = [
|
74
|
+
[
|
75
|
+
{content: "<b>#{company.fetch(:name)}</b>\n#{company_details}", padding: [0, 12, 0, 0]},
|
76
|
+
{content: Array(recipient).join("\n"), padding: [0, 12, 0, 0]}
|
77
|
+
]
|
78
|
+
]
|
79
|
+
table(line_items, width: bounds.width, cell_style: {borders: [], inline_format: true, overflow: :expand})
|
80
|
+
end
|
81
|
+
|
82
|
+
def render_line_items(line_items, margin_top: 30)
|
83
|
+
move_down margin_top
|
84
|
+
|
85
|
+
borders = line_items.length - 2
|
86
|
+
table(line_items, width: bounds.width, cell_style: {border_color: "eeeeee", inline_format: true}) do
|
87
|
+
cells.padding = 6
|
88
|
+
cells.borders = []
|
89
|
+
row(0..borders).borders = [:bottom]
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def render_footer(message, margin_top: 30)
|
94
|
+
move_down margin_top
|
95
|
+
text message, inline_format: true
|
96
|
+
end
|
97
|
+
|
98
|
+
def default_message(company:)
|
99
|
+
"For questions, contact us anytime at <color rgb='326d92'><link href='mailto:#{company.fetch(:email)}?subject=Question about my receipt'><b>#{company.fetch(:email)}</b></link></color>."
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
data/lib/receipts/invoice.rb
CHANGED
@@ -1,125 +1,5 @@
|
|
1
|
-
require 'prawn'
|
2
|
-
require 'prawn/table'
|
3
|
-
|
4
1
|
module Receipts
|
5
|
-
class Invoice <
|
6
|
-
|
7
|
-
|
8
|
-
def initialize(attributes)
|
9
|
-
@attributes = attributes
|
10
|
-
@id = attributes.fetch(:id)
|
11
|
-
@company = attributes.fetch(:company)
|
12
|
-
@line_items = attributes.fetch(:line_items)
|
13
|
-
@custom_font = attributes.fetch(:font, {})
|
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
|
-
|
21
|
-
super(margin: 0)
|
22
|
-
|
23
|
-
setup_fonts if custom_font.any?
|
24
|
-
generate
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
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
|
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"
|
82
|
-
|
83
|
-
move_down 5
|
84
|
-
text issue_date.to_s, inline_format: true, size: 12, leading: 4
|
85
|
-
|
86
|
-
move_down 10
|
87
|
-
label "DUE DATE"
|
88
|
-
|
89
|
-
move_down 5
|
90
|
-
text due_date.to_s, inline_format: true, size: 12, leading: 4
|
91
|
-
|
92
|
-
move_down 10
|
93
|
-
label "STATUS"
|
94
|
-
|
95
|
-
move_down 5
|
96
|
-
text status, inline_format: true, size: 12, leading: 4
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
def charge_details
|
101
|
-
move_down 30
|
102
|
-
|
103
|
-
borders = line_items.length - 2
|
104
|
-
|
105
|
-
table(line_items, width: bounds.width, cell_style: { border_color: 'cccccc', inline_format: true }) do
|
106
|
-
cells.padding = 12
|
107
|
-
cells.borders = []
|
108
|
-
row(0..borders).borders = [:bottom]
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
def footer
|
113
|
-
move_down 30
|
114
|
-
text message, inline_format: true, size: 12, leading: 4
|
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
|
120
|
-
|
121
|
-
def label(text)
|
122
|
-
text "<color rgb='a6a6a6'>#{text}</color>", inline_format: true, size: 8
|
123
|
-
end
|
2
|
+
class Invoice < Base
|
3
|
+
@title = "Invoice"
|
124
4
|
end
|
125
5
|
end
|
data/lib/receipts/receipt.rb
CHANGED
@@ -1,86 +1,5 @@
|
|
1
|
-
require 'prawn'
|
2
|
-
require 'prawn/table'
|
3
|
-
|
4
1
|
module Receipts
|
5
|
-
class Receipt <
|
6
|
-
|
7
|
-
|
8
|
-
def initialize(attributes)
|
9
|
-
@attributes = attributes
|
10
|
-
@id = attributes.fetch(:id)
|
11
|
-
@company = attributes.fetch(:company)
|
12
|
-
@line_items = attributes.fetch(:line_items)
|
13
|
-
@custom_font = attributes.fetch(:font, {})
|
14
|
-
@message = attributes.fetch(:message) { default_message }
|
15
|
-
@subheading = attributes.fetch(:subheading) { default_subheading }
|
16
|
-
|
17
|
-
super(margin: 0)
|
18
|
-
|
19
|
-
setup_fonts if custom_font.any?
|
20
|
-
generate
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def default_message
|
26
|
-
"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>."
|
27
|
-
end
|
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
|
47
|
-
|
48
|
-
def header
|
49
|
-
move_down 60
|
50
|
-
|
51
|
-
logo = company[:logo]
|
52
|
-
|
53
|
-
if logo.nil?
|
54
|
-
move_down 32
|
55
|
-
elsif logo.is_a?(String)
|
56
|
-
image open(logo), height: 32
|
57
|
-
else
|
58
|
-
image logo, height: 32
|
59
|
-
end
|
60
|
-
|
61
|
-
move_down 8
|
62
|
-
text "<color rgb='a6a6a6'>#{subheading % { id: id }}</color>", inline_format: true
|
63
|
-
|
64
|
-
move_down 30
|
65
|
-
text message, inline_format: true, size: 12.5, leading: 4
|
66
|
-
end
|
67
|
-
|
68
|
-
def charge_details
|
69
|
-
move_down 30
|
70
|
-
|
71
|
-
borders = line_items.length - 2
|
72
|
-
|
73
|
-
table(line_items, width: bounds.width, cell_style: { border_color: 'cccccc', inline_format: true }) do
|
74
|
-
cells.padding = 12
|
75
|
-
cells.borders = []
|
76
|
-
row(0..borders).borders = [:bottom]
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def footer
|
81
|
-
move_down 45
|
82
|
-
text company.fetch(:name), inline_format: true
|
83
|
-
text "<color rgb='888888'>#{company.fetch(:address)}</color>", inline_format: true
|
84
|
-
end
|
2
|
+
class Receipt < Base
|
3
|
+
@title = "Receipt"
|
85
4
|
end
|
86
5
|
end
|
data/lib/receipts/version.rb
CHANGED
data/lib/receipts.rb
CHANGED
@@ -1,3 +1,11 @@
|
|
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 :Base, "receipts/base"
|
8
|
+
autoload :Invoice, "receipts/invoice"
|
9
|
+
autoload :Receipt, "receipts/receipt"
|
10
|
+
autoload :Statement, "receipts/statement"
|
11
|
+
end
|
data/receipts.gemspec
CHANGED
@@ -1,28 +1,33 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
4
|
-
require 'receipts/version'
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/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 = %q{Receipts for your Rails application that works with any payment provider.}
|
12
|
-
spec.description = %q{Receipts for your Rails application that works with any payment provider.}
|
13
|
-
spec.homepage = ""
|
14
|
-
spec.license = "MIT"
|
6
|
+
spec.name = "receipts"
|
7
|
+
spec.version = Receipts::VERSION
|
8
|
+
spec.authors = ["Chris Oliver"]
|
9
|
+
spec.email = ["excid3@gmail.com"]
|
15
10
|
|
16
|
-
spec.
|
17
|
-
spec.
|
18
|
-
spec.
|
19
|
-
spec.
|
11
|
+
spec.summary = "Receipts for your Rails application that works with any payment provider."
|
12
|
+
spec.description = "Receipts for your Rails application that works with any payment provider."
|
13
|
+
spec.homepage = "https://github.com/excid3/receipts"
|
14
|
+
spec.license = "MIT"
|
20
15
|
|
21
|
-
spec.
|
22
|
-
spec.
|
23
|
-
spec.
|
24
|
-
|
16
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
17
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
18
|
+
spec.metadata["changelog_uri"] = "https://github.com/excid3/receipts/blob/master/CHANGELOG.md"
|
19
|
+
|
20
|
+
# Specify which files should be added to the gem when it is released.
|
21
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
22
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
23
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
24
|
+
(f == __FILE__) || f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
25
|
+
end
|
26
|
+
end
|
27
|
+
spec.bindir = "exe"
|
28
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
29
|
+
spec.require_paths = ["lib"]
|
25
30
|
|
26
|
-
spec.add_dependency
|
27
|
-
spec.add_dependency
|
31
|
+
spec.add_dependency "prawn", ">= 1.3.0", "< 3.0.0"
|
32
|
+
spec.add_dependency "prawn-table", "~> 0.2.1"
|
28
33
|
end
|
metadata
CHANGED
@@ -1,71 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: receipts
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Oliver
|
8
|
-
autorequire:
|
9
|
-
bindir:
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: bundler
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: rake
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '10.0'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '10.0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: rspec
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: pry
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
69
13
|
- !ruby/object:Gem::Dependency
|
70
14
|
name: prawn
|
71
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -107,29 +51,31 @@ executables: []
|
|
107
51
|
extensions: []
|
108
52
|
extra_rdoc_files: []
|
109
53
|
files:
|
110
|
-
- ".github/FUNDING.yml"
|
111
|
-
- ".gitignore"
|
112
|
-
- ".travis.yml"
|
113
54
|
- CHANGELOG.md
|
114
55
|
- Gemfile
|
115
56
|
- LICENSE.txt
|
116
57
|
- README.md
|
117
58
|
- Rakefile
|
118
|
-
- examples/
|
59
|
+
- examples/images/logo.png
|
60
|
+
- examples/images/options.jpg
|
119
61
|
- examples/invoice.pdf
|
120
62
|
- examples/receipt.pdf
|
63
|
+
- examples/statement.pdf
|
121
64
|
- lib/receipts.rb
|
65
|
+
- lib/receipts/base.rb
|
122
66
|
- lib/receipts/invoice.rb
|
123
67
|
- lib/receipts/receipt.rb
|
68
|
+
- lib/receipts/statement.rb
|
124
69
|
- lib/receipts/version.rb
|
125
70
|
- receipts.gemspec
|
126
|
-
|
127
|
-
- spec/spec_helper.rb
|
128
|
-
homepage: ''
|
71
|
+
homepage: https://github.com/excid3/receipts
|
129
72
|
licenses:
|
130
73
|
- MIT
|
131
|
-
metadata:
|
132
|
-
|
74
|
+
metadata:
|
75
|
+
homepage_uri: https://github.com/excid3/receipts
|
76
|
+
source_code_uri: https://github.com/excid3/receipts
|
77
|
+
changelog_uri: https://github.com/excid3/receipts/blob/master/CHANGELOG.md
|
78
|
+
post_install_message:
|
133
79
|
rdoc_options: []
|
134
80
|
require_paths:
|
135
81
|
- lib
|
@@ -144,10 +90,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
144
90
|
- !ruby/object:Gem::Version
|
145
91
|
version: '0'
|
146
92
|
requirements: []
|
147
|
-
rubygems_version: 3.
|
148
|
-
signing_key:
|
93
|
+
rubygems_version: 3.2.32
|
94
|
+
signing_key:
|
149
95
|
specification_version: 4
|
150
96
|
summary: Receipts for your Rails application that works with any payment provider.
|
151
|
-
test_files:
|
152
|
-
- spec/receipts_spec.rb
|
153
|
-
- spec/spec_helper.rb
|
97
|
+
test_files: []
|
data/.github/FUNDING.yml
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
# These are supported funding model platforms
|
2
|
-
|
3
|
-
github: [excid3] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
4
|
-
patreon: # Replace with a single Patreon username
|
5
|
-
open_collective: # Replace with a single Open Collective username
|
6
|
-
ko_fi: # Replace with a single Ko-fi username
|
7
|
-
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
8
|
-
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
9
|
-
liberapay: # Replace with a single Liberapay username
|
10
|
-
issuehunt: # Replace with a single IssueHunt username
|
11
|
-
otechie: # Replace with a single Otechie username
|
12
|
-
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
data/.gitignore
DELETED
data/.travis.yml
DELETED
data/spec/receipts_spec.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Receipts do
|
4
|
-
it "lets you create a new receipt" do
|
5
|
-
expect(Receipts::Receipt.new(
|
6
|
-
id: 1,
|
7
|
-
product: "GoRails",
|
8
|
-
company: {
|
9
|
-
name: "One Month, Inc.",
|
10
|
-
address: "37 Great Jones\nFloor 2\nNew York City, NY 10012",
|
11
|
-
email: "teachers@onemonth.com"
|
12
|
-
},
|
13
|
-
line_items: [
|
14
|
-
["Product", "GoRails"],
|
15
|
-
],
|
16
|
-
).class.name).to eq("Receipts::Receipt")
|
17
|
-
end
|
18
|
-
end
|