Skip to content

Commit

Permalink
Add invoices
Browse files Browse the repository at this point in the history
  • Loading branch information
excid3 committed Feb 24, 2020
1 parent 5b086ff commit c714e45
Show file tree
Hide file tree
Showing 11 changed files with 229 additions and 3 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@
*.o
*.a
mkmf.log
.DS_Store
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
### 1.0.0

* [NEW] Invoices!
45 changes: 44 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

Receipts for your Rails application that works with any payment provider.

Check out an [example PDF receipt](https://github.com/excid3/receipts/blob/master/examples/receipt.pdf?raw=true)
Check out the [example receipt](https://github.com/excid3/receipts/blob/master/examples/receipt.pdf?raw=true) and [example invoice](https://github.com/excid3/receipts/blob/master/examples/invoice.pdf?raw=true) PDFs.

## Installation

Expand Down Expand Up @@ -170,6 +170,49 @@ resources :charges
<%= link_to "Download Receipt", charge_path(@charge, format: :pdf) %>
```

## Invoices

Invoices follow the exact same set of steps as above, with a few minor changes and have a few extra arguments you can use:

* `issue_date` - Date the invoice was issued

* `due_date` - Date the invoice payment is due

* `status` - A status for the invoice (Pending, Paid, etc)

* `bill_to` - A string or Array of lines with billing details

You can also use line_items to flexibly generate and display the table with items in it, including subtotal, taxes, and total amount.

```ruby
Receipts::Invoice.new(
id: "123",
issue_date: Date.today,
due_date: Date.today + 30,
status: "<b><color rgb='#5eba7d'>PAID</color></b>",
bill_to: [
"GoRails, LLC",
"Address",
"City, State Zipcode",
nil,
"[email protected]",
],
company: {
name: "GoRails, LLC",
address: "123 Fake Street\nNew York City, NY 10012",
email: "[email protected]",
logo: File.expand_path("./examples/gorails.png")
},
line_items: [
["<b>Item</b>", "<b>Unit Cost</b>", "<b>Quantity</b>", "<b>Amount</b>"],
["GoRails Subscription", "$19.00", "1", "$19.00"],
[nil, nil, "Subtotal", "$19.00"],
[nil, nil, "Tax Rate", "0%"],
[nil, nil, "Total", "$19.00"],
],
)
```

## Contributing

1. Fork it ( https://github.com/[my-github-username]/receipts/fork )
Expand Down
55 changes: 55 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,58 @@ task :test => :spec
task :console do
exec "irb -r receipts -I ./lib"
end

task :receipt do
require "./lib/receipts"

Receipts::Receipt.new(
id: "123",
subheading: "RECEIPT FOR CHARGE #1",
product: "GoRails",
company: {
name: "GoRails, LLC",
address: "123 Fake Street\nNew York City, NY 10012",
email: "[email protected]",
logo: File.expand_path("./examples/gorails.png")
},
line_items: [
["Date", Time.now.to_s],
["Account Billed", "Example User ([email protected])"],
["Product", "GoRails"],
["Amount", "$19.00"],
["Charged to", "Visa (**** **** **** 1234)"],
["Transaction ID", "123456"]
],
).render_file "examples/receipt.pdf"
end

task :invoice do
require "./lib/receipts"

Receipts::Invoice.new(
id: "123",
issue_date: Date.today,
due_date: Date.today + 30,
status: "<b><color rgb='#5eba7d'>PAID</color></b>",
bill_to: [
"GoRails, LLC",
"Address",
"City, State Zipcode",
nil,
"[email protected]",
],
company: {
name: "GoRails, LLC",
address: "123 Fake Street\nNew York City, NY 10012",
email: "[email protected]",
logo: File.expand_path("./examples/gorails.png")
},
line_items: [
["<b>Item</b>", "<b>Unit Cost</b>", "<b>Quantity</b>", "<b>Amount</b>"],
["GoRails Subscription", "$19.00", "1", "$19.00"],
[nil, nil, "Subtotal", "$19.00"],
[nil, nil, "Tax Rate", "0%"],
[nil, nil, "Amount Due", "$19.00"],
],
).render_file "examples/invoice.pdf"
end
Binary file added examples/gorails.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/invoice.pdf
Binary file not shown.
Binary file modified examples/receipt.pdf
Binary file not shown.
1 change: 1 addition & 0 deletions lib/receipts.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
require "receipts/version"
require "receipts/receipt"
require "receipts/invoice"
123 changes: 123 additions & 0 deletions lib/receipts/invoice.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
require 'prawn'
require 'prawn/table'

module Receipts
class Invoice < Prawn::Document
attr_reader :attributes, :id, :company, :custom_font, :line_items, :logo, :message, :product, :subheading, :bill_to, :issue_date, :due_date, :status

def initialize(attributes)
@attributes = attributes
@id = attributes.fetch(:id)
@company = attributes.fetch(:company)
@line_items = attributes.fetch(:line_items)
@custom_font = attributes.fetch(:font, {})
@message = attributes.fetch(:message) { default_message }
@subheading = attributes.fetch(:subheading) { default_subheading }
@bill_to = Array(attributes.fetch(:bill_to)).join("\n")
@issue_date = attributes.fetch(:issue_date)
@due_date = attributes.fetch(:due_date)
@status = attributes.fetch(:status)

super(margin: 0)

setup_fonts if custom_font.any?
generate
end

private

def default_message
"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>."
end

def default_subheading
"INVOICE #%{id}"
end

def setup_fonts
font_families.update "Primary" => custom_font
font "Primary"
end

def generate
bounding_box [0, 792], width: 612, height: 792 do
bounding_box [85, 792], width: 442, height: 792 do
header
charge_details
footer
end
end
end

def header
move_down 60

logo_path = company.fetch(:logo, '')

if logo_path.empty?
move_down 32
else
image open(logo_path), height: 32
end

move_down 8
label (subheading % {id: id})

move_down 10

# Cache the Y value so we can have both boxes at the same height
top = y
bounding_box([0, y], width: 200) do
label "BILL TO"

move_down 5
text_box bill_to, at: [0, cursor], width: 200, height: 75, inline_format: true, size: 10, leading: 4, overflow: :shrink_to_fit

end

bounding_box([250, top], width: 200) do
label "INVOICE DATE"

move_down 5
text issue_date.to_s, inline_format: true, size: 12, leading: 4

move_down 10
label "DUE DATE"

move_down 5
text due_date.to_s, inline_format: true, size: 12, leading: 4

move_down 10
label "STATUS"

move_down 5
text status, inline_format: true, size: 12, leading: 4
end
end

def charge_details
move_down 30

borders = line_items.length - 2

table(line_items, cell_style: { border_color: 'cccccc', inline_format: true }) do
cells.padding = 12
cells.borders = []
row(0..borders).borders = [:bottom]
end
end

def footer
move_down 30
text message, inline_format: true, size: 12, leading: 4

move_down 30
text company.fetch(:name), inline_format: true
text "<color rgb='888888'>#{company.fetch(:address)}</color>", inline_format: true
end

def label(text)
text "<color rgb='a6a6a6'>#{text}</color>", inline_format: true, size: 8
end
end
end
2 changes: 1 addition & 1 deletion lib/receipts/receipt.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def charge_details

borders = line_items.length - 2

table(line_items, cell_style: { border_color: 'cccccc' }) do
table(line_items, cell_style: { border_color: 'cccccc', inline_format: true }) do
cells.padding = 12
cells.borders = []
row(0..borders).borders = [:bottom]
Expand Down
2 changes: 1 addition & 1 deletion lib/receipts/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Receipts
VERSION = "0.2.3"
VERSION = "1.0.0"
end

0 comments on commit c714e45

Please sign in to comment.