![travisci](https://api.travis-ci.org/excid3/receipts.svg) # Receipts Gem Receipts, Invoices, and Statements for your Rails application that works with any payment provider. Receipts uses Prawn to generate the PDFs. Check out the [example PDFs](https://github.com/excid3/receipts/blob/master/examples/). ## Installation Add this line to your application's Gemfile: ```ruby gem 'receipts' ``` And then execute: $ bundle Or install it yourself as: $ gem install receipts ## Usage To generate a Receipt, Invoice, or Statement, create an instance and provide content to render: ```ruby r = Receipts::Receipt.new( details: [ ["Receipt Number", "123"], ["Date paid", Date.today], ["Payment method", "ACH super long super long super long super long super long"] ], company: { name: "Example, LLC", address: "123 Fake Street\nNew York City, NY 10012", email: "support@example.com", logo: File.expand_path("./examples/images/logo.png") }, recipient: [ "Customer", "Their Address", "City, State Zipcode", nil, "customer@example.org" ], line_items: [ ["Item", "Unit Cost", "Quantity", "Amount"], ["Subscription", "$19.00", "1", "$19.00"], [nil, nil, "Subtotal", "$19.00"], [nil, nil, "Tax", "$1.12"], [nil, nil, "Total", "$20.12"], [nil, nil, "Amount paid", "$20.12"], [nil, nil, "Refunded on #{Date.today}", "$5.00"] ], footer: "Thanks for your business. Please contact us if you have any questions." ) # Returns a string of the raw PDF r.render # Writes the PDF to disk r.render_file "examples/receipt.pdf" ``` ### Options You can pass the following options to generate a PDF: * `recipient` - Array of customer details to include. Typically, this is name, address, email, VAT ID, etc. * `company` - Hash of your company details * `name` - Company name * `address` - Company address * `email` - Company support email address * `phone` - Company phone number - _Optional_ * `logo` - Logo to be displayed on the receipt - _Optional_ This can be either a Path, File, StringIO, or URL. Here are a few examples: ```ruby logo: Rails.root.join("app/assets/images/logo.png") logo: File.expand_path("./logo.png") logo: File.open("app/assets/images/logo.png", "rb") logo: "https://www.ruby-lang.org/images/header-ruby-logo@2x.png" # Downloaded with OpenURI ``` * `details` - Array of details about the Receipt, Invoice, Statement. Typically, this is receipt numbers, issue date, due date, status, etc. * `line_items` - Array of line items to be displayed in table format. * `footer` - String for a message at the bottom of the PDF. * `font` - Hash of paths to font files - _Optional_ ```ruby font: { bold: Rails.root.join('app/assets/fonts/tradegothic/TradeGothic-Bold.ttf'), normal: Rails.root.join('app/assets/fonts/tradegothic/TradeGothic.ttf'), } ``` Here's an example of where each option is displayed. ![options](examples/images/options.jpg) ### Formatting `details` and `line_items` allow inline formatting with Prawn. This allows you to use HTML tags to format text: `` `` `` `` `` `` `` `` `` See [the Prawn docs](https://prawnpdf.org/api-docs/2.3.0/Prawn/Text.html#text-instance_method) for more information. ### Internationalization (I18n) You can use `I18n.t` when rendering your receipts to internationalize them. ```ruby line_items: [ [I18n.t("receipts.date"), created_at.to_s], [I18n.t("receipts.product"), "GoRails"], [I18n.t("receipts.transaction"), uuid] ] ``` ### Custom PDF Content You can change the entire PDF content by instantiating an Receipts object without any options. ```ruby receipt = Receipts::Receipt.new # creates an empty PDF ``` Each Receipts object inherits from Prawn::Document. This allows you to choose what is rendered and include any custom Prawn content you like. ```ruby receipt.text("hello world") ``` You can also use the Receipts helpers in your custom PDFs at the current cursor position. ```ruby receipt.text("Custom header") receipt.render_line_items([ ["my line items"] ]) receipt.render_footer("This is a custom footer using the Receipts helper") ``` ### Rendering PDFs To render a PDF in memory, use `render`. This is recommended for serving PDFs in your Rails controllers. ```ruby receipt.render ``` To render a PDF to disk, use `render_file`: ```ruby receipt.render_file "receipt.pdf" ``` ## Rendering PDFs in Rails controller actions 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. The `Charge` model has a `receipt` method that returns a `Receipts::Receipt` instance with all the receipt data filled out. Then we can `render` to generate the PDF in memory. This produces a String with the raw PDF data in it. Using `send_data` from Rails, we can send the PDF contents and provide the browser with a recommended filename, content type and disposition. ```ruby class ChargesController < ApplicationController before_action :authenticate_user! before_action :set_charge def show respond_to do |format| format.pdf { send_pdf } end end private def set_charge @charge = current_user.charges.find(params[:id]) end def send_pdf # Render the PDF in memory and send as the response send_data @charge.receipt.render, filename: "#{@charge.created_at.strftime("%Y-%m-%d")}-gorails-receipt.pdf", type: "application/pdf", disposition: :inline # or :attachment to download end end ``` Then, just `link_to` to your charge with the format of `pdf`. For example: ```ruby # config/routes.rb resources :charges ``` ```erb <%= link_to "View Receipt", charge_path(@charge, format: :pdf) %> ``` ## Invoices 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. ```ruby Receipts::Invoice.new( details: [ ["Invoice Number", "123"], ["Issue Date", Date.today.strftime("%B %d, %Y")], ["Due Date", Date.today.strftime("%B %d, %Y")], ["Status", "PAID"] ], recipient: [ "Bill To", "Customer", "Address", "City, State Zipcode", "customer@example.org" ], company: { name: "Example, LLC", address: "123 Fake Street\nNew York City, NY 10012", phone: "(555) 867-5309", email: "support@example.com", logo: File.expand_path("./examples/images/logo.png") }, line_items: [ ["Item", "Unit Cost", "Quantity", "Amount"], ["Subscription", "$19.00", "1", "$19.00"], [nil, nil, "Subtotal", "$19.00"], [nil, nil, "Tax Rate", "0%"], [nil, nil, "Amount Due", "$19.00"] ] ) ``` ## Statements 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. ```ruby Receipts::Statement.new( details: [ ["Statement Number", "123"], ["Issue Date", Date.today.strftime("%B %d, %Y")], ["Period", "#{(Date.today - 30).strftime("%B %d, %Y")} - #{Date.today.strftime("%B %d, %Y")}"] ], recipient: [ "Bill To", "Customer", "Address", "City, State Zipcode", "customer@example.org" ], company: { name: "Example, LLC", address: "123 Fake Street\nNew York City, NY 10012", email: "support@example.com", phone: "(555) 867-5309", logo: File.expand_path("./examples/images/logo.png") }, line_items: [ ["Item", "Unit Cost", "Quantity", "Amount"], ["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/excid3/receipts/fork ) 2. Create your feature branch (`git checkout -b my-new-feature`) 3. Commit your changes (`git commit -am 'Add some feature'`) 4. Push to the branch (`git push origin my-new-feature`) 5. Create a new Pull Request