invoicepdf 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Drew Tempelmeyer
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,63 @@
1
+ = InvoicePDF
2
+
3
+ InvoicePDF is a Ruby gem to easily create PDF invoices within your application.
4
+
5
+ I created this to be easily extensible by creating and specifying your own generators to create
6
+ invoices fit for your use.
7
+
8
+ == Getting Started
9
+ 1. Install InvoicePDF as you would any other gem
10
+ gem install invoicepdf
11
+
12
+ 2. Include the gem in your Gemfile for Rails applications
13
+ gem "invoicepdf"
14
+
15
+ 3. Start using it in your application
16
+ invoice = InvoicePDF::Invoice.new( :company => "Drew Tempelmeyer", :company_address => "555 55th St\nNew York, NY 00000", :bill_to => "John Doe", :number => "AZ-100", :notes => "Test invoice")
17
+ invoice.items << InvoicePDF::LineItem.new(:description => "Here is a line item", :price => 495.00, :quantity => 5)
18
+ invoice.save
19
+
20
+ === Using a generator
21
+ Generators are what actually create the PDF. This allows you to customize the appearance of your invoice by creating a new generator.
22
+ Have a look at lib/generators/standard.rb for an example.
23
+
24
+ Specifying the generator to use is easy. When creating your Invoice object, use the <tt>:generator</tt> attribute.
25
+ invoice = InvoicePDF::Invoice.new( :generator => InvoicePDF::Generators::Standard.new, :company => "Drew Tempelmeyer", :company_address => "555 55th St\nNew York, NY 00000", :bill_to => "John Doe", :number => "AZ-100", :notes => "Test invoice")
26
+
27
+ We're using the InvoicePDF::Generators::Standard generator to create our invoice. When you save the invoice, it will call the <tt>create_pdf</tt> method inside your generator
28
+ (in this example InvoicePDF::Generators::Standard.create_pdf).
29
+
30
+ === Creating a generator
31
+ All generators should be contained within the InvoicePDF::Generators module. Your generator needs to have the <tt>create_pdf</tt> method.
32
+
33
+ A barebones generator would look something like the following
34
+ module InvoicePDF
35
+ module Generators
36
+ class Barebone
37
+ include InvoicePDF::Helpers # if you need the helpers
38
+ def create_pdf( invoice )
39
+ Prawn::Document.generate("#{invoice.file_path}/#{invoice.file_name}", :dpi => 72) do |pdf|
40
+ pdf.text "Invoice #{invoice.number}"
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ This would simply create a PDF in your specified directory with the specified file name.
48
+
49
+ PDF generation is done by using the Prawn gem (http://prawn.majesticseacreature.com/docs/).
50
+
51
+ == Contributing to InvoicePDF
52
+
53
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
54
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
55
+ * Fork the project
56
+ * Start a feature/bugfix branch
57
+ * Commit and push until you are happy with your contribution
58
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
59
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
60
+
61
+ == Copyright
62
+
63
+ Copyright (c) 2010 Drew Tempelmeyer. See LICENSE.txt for further details.
data/Rakefile ADDED
@@ -0,0 +1,53 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'rake'
11
+
12
+ require 'jeweler'
13
+ Jeweler::Tasks.new do |gem|
14
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
15
+ gem.name = "invoicepdf"
16
+ gem.homepage = "http://github.com/drewtempelmeyer/invoicepdf"
17
+ gem.license = "MIT"
18
+ gem.summary = %Q{Easily create PDF invoices}
19
+ gem.description = %Q{Easily create PDF invoices}
20
+ gem.email = "drewtemp@gmail.com"
21
+ gem.authors = ["Drew Tempelmeyer"]
22
+ gem.add_runtime_dependency 'prawn'
23
+ gem.files = FileList['Rakefile', 'lib/**/*.rb', 'init.rb']
24
+ gem.rubyforge_project = 'invoicepdf'
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rake/testtask'
29
+ Rake::TestTask.new(:test) do |test|
30
+ test.libs << 'lib' << 'test'
31
+ test.pattern = 'test/**/test_*.rb'
32
+ test.verbose = true
33
+ end
34
+
35
+ require 'rcov/rcovtask'
36
+ Rcov::RcovTask.new do |test|
37
+ test.libs << 'test'
38
+ test.pattern = 'test/**/test_*.rb'
39
+ test.verbose = true
40
+ end
41
+
42
+ task :default => :test
43
+
44
+ require 'rake/rdoctask'
45
+ Rake::RDocTask.new do |rdoc|
46
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
47
+
48
+ rdoc.rdoc_dir = 'rdoc'
49
+ rdoc.title = "invoicepdf #{version}"
50
+ rdoc.options << '-f' << 'horo'
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'invoicepdf'
@@ -0,0 +1,127 @@
1
+ module InvoicePDF
2
+
3
+ # Generators should be contained within the <tt>InvoicePDF::Generators</tt> module.
4
+ module Generators
5
+
6
+ # The default InvoicePDF generator.
7
+ class Standard
8
+ include InvoicePDF::Helpers
9
+
10
+ # Constructor here for future use... maybe.
11
+ def initialize( options = {} ); end
12
+
13
+ # Called from <tt>InvoicePDF::Invoice.save</tt>. +invoice+ is the <tt>InvoicePDF::Invoice</tt> instance.
14
+ def create_pdf( invoice )
15
+ money_maker_options = {
16
+ :currency_symbol => invoice.currency,
17
+ :delimiter => invoice.separator,
18
+ :decimal_symbol => invoice.decimal,
19
+ :after_text => invoice.currency_text
20
+ }
21
+
22
+ # The below line should remain consistent across all generators. We don't want mysteriously placed PDF files.
23
+ Prawn::Document.generate("#{invoice.file_path}/#{invoice.file_name}", :dpi => 72) do |pdf|
24
+ pdf.move_down 10
25
+
26
+ # Set the default type
27
+ pdf.font 'Helvetica', :size => 9
28
+
29
+ # Draw the company name
30
+ pdf.text invoice.company, :style => :bold, :size => 20
31
+
32
+ # Invoice information
33
+ pdf.bounding_box [ pdf.bounds.right - 200, pdf.bounds.top - 2 ], :width => 250 do
34
+ data = [
35
+ [ { :text => 'Invoice Number', :font_style => :bold }, invoice.number ],
36
+ [ { :text => 'Invoice Date', :font_style => :bold }, invoice.invoice_date ],
37
+ [ { :text => 'Due Date', :font_style => :bold }, invoice.due_date ]
38
+ ]
39
+
40
+ data.insert( 1, [ { :text => 'PO Number', :font_style => :bold }, invoice.po_number ] ) unless invoice.po_number.nil?
41
+
42
+ pdf.table data,
43
+ :border_style => :underline_header,
44
+ :font_size => 9,
45
+ :horizontal_padding => 2,
46
+ :vertical_padding => 1,
47
+ :column_widths => { 0 => 100, 1 => 150 },
48
+ :position => :left,
49
+ :align => { 0 => :left, 1 => :left }
50
+ end
51
+ # End bounding_box
52
+
53
+ pdf.move_down 65
54
+
55
+ var_y = pdf.y
56
+
57
+ # Bill to section
58
+ pdf.bounding_box [ 0, var_y ], :width => ( pdf.bounds.right / 3 ) do
59
+ pdf.text 'Bill To', :style => :bold
60
+ pdf.text "#{invoice.bill_to}\n#{invoice.bill_to_address}"
61
+ end
62
+ # End bill to section
63
+
64
+ # Company address section
65
+ pdf.bounding_box [ ( pdf.bounds.right / 3 ), var_y ], :width => ( pdf.bounds.right / 3 ) do
66
+ pdf.text 'Pay To', :style => :bold
67
+ pdf.text "#{invoice.company}\n#{invoice.company_address}"
68
+ end
69
+ # End company address section
70
+
71
+ pdf.move_down 40
72
+
73
+ # Create items array for storage of invoice items
74
+ items = []
75
+ invoice.items.map { |item| items << [ item.description, item.quantity, money_maker(item.price, money_maker_options), money_maker(item.total, money_maker_options) ] }
76
+
77
+ # Insert subtotal
78
+ items << [ { :text => 'Subtotal', :align => :right, :colspan => 3 }, money_maker(invoice.subtotal, money_maker_options) ]
79
+
80
+ # Insert discount
81
+ items << [ { :text => "Discount (#{invoice.discount}%)", :align => :right, :colspan => 3 }, money_maker(invoice.discount_amount, money_maker_options) ] if invoice.discount_amount > 0
82
+
83
+ # Insert tax amount
84
+ items << [ { :text => "Tax (#{invoice.tax}%)", :align => :right, :colspan => 3 }, money_maker(invoice.tax_amount, money_maker_options) ] if invoice.tax_amount > 0
85
+
86
+ # Insert total
87
+ items << [ { :text => "Total", :align => :right, :colspan => 3 }, money_maker(invoice.total, money_maker_options) ]
88
+
89
+ # Insert amount paid
90
+ items << [ { :text => "Amount Paid", :align => :right, :colspan => 3 }, money_maker(invoice.paid, money_maker_options) ] if invoice.paid > 0
91
+
92
+ # Insert total due
93
+ items << [ { :text => "Amount Due", :align => :right, :colspan => 3, :font_style => :bold }, money_maker(invoice.total_due, money_maker_options) ]
94
+
95
+ # Create items table
96
+ pdf.table items,
97
+ :border_style => :underline_header,
98
+ :border_width => 0,
99
+ :border_color => '000000',
100
+ :font_size => 9,
101
+ :headers => [
102
+ { :text => 'Description', :font_style => :bold },
103
+ { :text => 'Qty', :font_style => :bold },
104
+ { :text => 'Price', :font_style => :bold },
105
+ { :text => 'Total', :font_style => :bold }
106
+ ],
107
+ :header_color => '000000',
108
+ :header_text_color => 'ffffff',
109
+ :align => { 0 => :left, 1 => :center, 2 => :center, 3 => :right },
110
+ :row_colors => [ 'ffffff', 'f0f0f0' ],
111
+ :width => pdf.bounds.right,
112
+ :column_widths => { 1 => 50, 2 => 75, 3 => 75 }
113
+
114
+ unless invoice.notes.nil?
115
+ pdf.move_down 50
116
+ pdf.text 'Notes', :size => 10, :style => :bold
117
+ pdf.text invoice.notes, :size => 8
118
+ end
119
+ end
120
+ # Done creating PDF
121
+
122
+ end
123
+
124
+ end
125
+
126
+ end
127
+ end
@@ -0,0 +1,34 @@
1
+ module InvoicePDF
2
+ # Helpers to be used in InvoicePDF::Generators
3
+ module Helpers
4
+
5
+ # Similar to Rails' number_to_currency, but we don't want to rely on Rails.
6
+ # Found the majority of this code online, but lost the URL. If this is yours, let me know and I'll give
7
+ # credit.
8
+ #
9
+ # Formats the +number+ into a currency format. You can customize the format in the +options+ hash.
10
+ #
11
+ # ==== Options
12
+ # * <tt>:currency_symbol</tt> - Currency symbol. (default is '$')
13
+ # * <tt>:delimiter</tt> - Thousands separator. (default is ',')
14
+ # * <tt>:decimal_symbol</tt> - Separates integer and fractional amounts (think dollars and cents). (default is '.')
15
+ # * <tt>:currency_before</tt> - Boolean to set placement of <tt>:currency_symbol</tt>. true for before number, false for after number. (default is true)
16
+ # * <tt>:after_text</tt> - Useful for displaying the currency after the number. (default is ' USD')
17
+ #
18
+ # ==== Example
19
+ # money_maker(1000) # => $1,000.00 USD
20
+ # money_maker(1000, :delimiter => '.', :decimal_symbol => ',', :after_text => '') # => $1.000,00
21
+ def money_maker( number, options = {} )
22
+ options = { :currency_symbol => '$', :delimiter => ',', :decimal_symbol => '.', :currency_before => true, :after_text => ' USD' }.merge(options)
23
+
24
+ # split integer and fractional parts
25
+ int, frac = ("%.2f" % number).split('.')
26
+
27
+ # insert delimiters
28
+ int.gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{options[:delimiter]}")
29
+
30
+ return options[:currency_symbol] + int + options[:decimal_symbol] + frac + options[:after_text] if options[:currency_before]
31
+ int + options[:decimal_symbol] + frac + options[:currency_symbol] + options[:after_text]
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,82 @@
1
+
2
+ # One module to rule them all
3
+ module InvoicePDF
4
+
5
+ # Invoice model to create your PDF invoices.
6
+ class Invoice
7
+
8
+ attr_accessor :generator, :file_name, :file_path, :company, :company_address, :bill_to, :bill_to_address, :invoice_date, :due_date,
9
+ :number, :po_number, :items, :tax, :discount, :paid, :notes, :currency, :separator, :decimal, :currency_text
10
+
11
+ # Creates a new Invoice object with the specified options
12
+ # ==== Options
13
+ # * <tt>:generator</tt> - An <tt>InvoicePDF::Generator</tt> that designs and creates the PDF. (default is InvoicePDF::Generators::Standard.new)
14
+ # * <tt>:file_path</tt> - The directory to store the generated invoice. (default is './')
15
+ # * <tt>:file_name</tt> - The file name of the PDF to save. (default is 'invoice.pdf')
16
+ # * <tt>:company</tt> - The company name that will appear on the top of the invoice and in the 'Bill To' section. (default is 'Company Name')
17
+ # * <tt>:company_address</tt> - Your company's address. Displayed in the 'Pay To' section. Use \n for line separation. (default is nil)
18
+ # * <tt>:bill_to</tt> - Person/company you're billing. (default is nil)
19
+ # * <tt>:bill_to_address</tt> - Address of the person/company you're billing to. Displayed in the 'Bill To' section. (default is nil)
20
+ # * <tt>:number</tt> - The invoice number. (default is '100')
21
+ # * <tt>:po_number</tt> - The purchase order number for the invoice. Excluded from the invoice if nil. (default is nil)
22
+ # * <tt>:invoice_date</tt> - The invoice date. (default is Time.now)
23
+ # * <tt>:due_date</tt> - The invoice due_date. You need your money by this time. (default is 15 days after Time.now)
24
+ # * <tt>:items</tt> - Array of <tt>LineItem</tt>s. (default is an empty array).
25
+ # * <tt>:discount</tt> - Discount to apply to the invoice. The value should not include the percent symbol. (default is nil)
26
+ # * <tt>:tax</tt> - Tax amount to apply to taxable <tt>LineItem</tt>s. The value should not include the percent symbol. (default is nil)
27
+ # * <tt>:paid</tt> - The amount already paid on the invoice. (default is 0)
28
+ # * <tt>:notes</tt> - Notes to display at the end of the invoice. (default is nil)
29
+ # * <tt>:currency</tt> - The currency symbol to use for formatting prices and totals. (default is '$')
30
+ # * <tt>:separator</tt> - The thousands separator for prices/totals. (default is ',')
31
+ # * <tt>:decimal</tt> - The separator between the integer and fractional value. Think dollars and cents. (default is '.')
32
+ # * <tt>:currency_text</tt> - Displays text after the formatted currency. Useful if you wanted to include the currency code (example: ' USD'). (default is '')
33
+ #
34
+ # ==== Examples
35
+ # invoice = InvoicePDF::Invoice.new( :company => "Drew Tempelmeyer", :company_address => "555 55th St\nNew York, NY 00000", :bill_to => "John Doe", :number => "AZ-100", :notes => "Test invoice")
36
+ # invoice.items << InvoicePDF::LineItem.new(:description => "Here is a line item", :price => 495.00, :quantity => 5)
37
+ # invoice.save
38
+ def initialize( options = {} )
39
+ options = { :generator => InvoicePDF::Generators::Standard.new, :file_path => './', :file_name => 'invoice.pdf', :company => 'Company Name', :number => '100',
40
+ :po_number => nil, :invoice_date => Time.now, :due_date => Time.now + ((60 * 60 * 24) * 15), :items => [], :discount => nil, :tax => nil, :paid => 0,
41
+ :notes => nil, :currency => '$', :separator => ',', :decimal => '.', :currency_text => '' }.merge(options)
42
+ options.each { |k,v| send("#{k}=", v) }
43
+ end
44
+
45
+ # Calculates the subtotal of the invoice
46
+ def subtotal
47
+ amount = 0
48
+ items.each { |item| amount += item.total }
49
+ amount
50
+ end
51
+
52
+ # Calculates the tax amount of the invoice based on taxable items
53
+ def tax_amount
54
+ return 0 if tax.nil? || tax <= 0
55
+ amount = 0
56
+ items.each { |item| amount += item.total if item.taxable? }
57
+ amount * ( tax / 100 )
58
+ end
59
+
60
+ # Calculates the discount amount if a discount is specified greater than 0
61
+ def discount_amount
62
+ return 0 if discount.nil? || discount <= 0
63
+ subtotal * ( discount / 100 )
64
+ end
65
+
66
+ # Calculates the total of the invoice with the discount and tax amount applied
67
+ def total
68
+ (subtotal - discount_amount) + tax_amount
69
+ end
70
+
71
+ # The total amount due (total - paid)
72
+ def total_due
73
+ total - paid
74
+ end
75
+
76
+ # Generates the PDF invoice and saves it to the specified destination
77
+ def save
78
+ generator.create_pdf( self )
79
+ end
80
+
81
+ end
82
+ end
@@ -0,0 +1,38 @@
1
+ module InvoicePDF #:nodoc#
2
+ # Line items for InvoicePDF::Invoice
3
+ class LineItem
4
+ attr_accessor :sku, :description, :price, :quantity, :taxable
5
+
6
+ # Creates a new <tt>LineItem</tt> to be added to the InvoicePDF::Invoice instance
7
+ #
8
+ # ==== Options
9
+ # * <tt>:sku</tt> - SKU of the item. (default is nil)
10
+ # * <tt>:description</tt> - Description of the item. (default is nil)
11
+ # * <tt>:price</tt> - Price of each item. (default is 0.00)
12
+ # * <tt>:quantity</tt> - Number of items. (default is 1)
13
+ # * <tt>:taxable</tt> - Is the item taxable? true/false. (default is false)
14
+ #
15
+ # ==== Example
16
+ # item = InvoicePDF::InvoiceItem.new(:description => "Test line item", :price => 495.00, :quantity => 5)
17
+ def initialize(options = {})
18
+ options = { :sku => nil, :description => nil, :quantity => 1, :price => 0.00, :taxable => false }.merge(options)
19
+ options.each { |k, v| send("#{k}=", v) }
20
+ end
21
+
22
+ # Asks if the item is taxable
23
+ # item = InvoicePDF::InvoiceItem.new(:description => "Test line item", :price => 495.00, :quantity => 5)
24
+ # item.taxable? # => false
25
+ def taxable?
26
+ return false if taxable.nil? || taxable == false
27
+ true
28
+ end
29
+
30
+ # Return the total amount of the <tt>LineItem</tt>
31
+ # item = InvoicePDF::InvoiceItem.new(:description => "Test line item", :price => 495.00, :quantity => 5)
32
+ # item.total # => 2475
33
+ def total
34
+ price * quantity
35
+ end
36
+
37
+ end
38
+ end
data/lib/invoicepdf.rb ADDED
@@ -0,0 +1,12 @@
1
+ module InvoicePDF
2
+ # InvoicePDF version
3
+ VERSION = "0.1.2"
4
+ end
5
+
6
+ require 'prawn'
7
+ require 'prawn/layout'
8
+ require 'invoice/invoice'
9
+ require 'invoice/line_item'
10
+ require 'invoice/helpers'
11
+
12
+ Dir[File.dirname(__FILE__) + '/generators/*.rb'].each { |file| require file }
data/test/helper.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+ require 'shoulda'
12
+
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ require 'invoice'
16
+
17
+ class Test::Unit::TestCase
18
+ end
@@ -0,0 +1,37 @@
1
+ require 'helper'
2
+
3
+ class TestInvoice < Test::Unit::TestCase
4
+
5
+ should "start a new invoice" do
6
+ invoice = InvoicePDF::Invoice.new(:company => 'Drew Tempelmeyer', :bill_to => 'Alyssa Smith', :notes => 'Pay up now, sucka')
7
+ assert_equal 'Drew Tempelmeyer', invoice.company
8
+ end
9
+
10
+ should "insert a new item into the invoice" do
11
+ invoice = InvoicePDF::Invoice.new({ :company => 'Drew Tempelmeyer', :bill_to => 'Alyssa Smith', :notes => 'Pay up now, sucka' })
12
+ invoice.items << InvoicePDF::LineItem.new({ :description => 'This is a line item', :price => 400, :quantity => 100 })
13
+ assert_equal 1, invoice.items.length
14
+ end
15
+
16
+ should "subtotal should equal 40000" do
17
+ invoice = InvoicePDF::Invoice.new({ :company => 'Drew Tempelmeyer', :bill_to => 'Alyssa Smith', :notes => 'Pay up now, sucka' })
18
+ invoice.items << InvoicePDF::LineItem.new({ :description => 'This is a line item', :price => 400, :quantity => 100 })
19
+ assert_equal 40000, invoice.subtotal
20
+ end
21
+
22
+ should "have paid half of the invoice" do
23
+ invoice = InvoicePDF::Invoice.new({ :company => 'Drew Tempelmeyer', :bill_to => 'Alyssa Smith', :notes => 'Pay up now, sucka' })
24
+ invoice.items << InvoicePDF::LineItem.new({ :description => 'This is a line item', :price => 400, :quantity => 100 })
25
+ invoice.paid = 20000
26
+ assert_equal 20000, invoice.total_due
27
+ end
28
+
29
+ should "save the PDF" do
30
+ invoice = InvoicePDF::Invoice.new({ :company => 'Drew Tempelmeyer', :bill_to => 'Alyssa Smith', :notes => 'Pay up now, sucka' })
31
+ invoice.items << InvoicePDF::LineItem.new({ :description => 'This is a line item', :price => 400, :quantity => 100 })
32
+ invoice.paid = 20000
33
+ invoice.save
34
+ assert_equal true, File.exist?('invoice.pdf')
35
+ end
36
+
37
+ end
metadata ADDED
@@ -0,0 +1,171 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: invoicepdf
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 4
9
+ version: 0.1.4
10
+ platform: ruby
11
+ authors:
12
+ - Drew Tempelmeyer
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-11-21 00:00:00 -06:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: prawn
22
+ requirement: &id001 !ruby/object:Gem::Requirement
23
+ none: false
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :runtime
31
+ prerelease: false
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: shoulda
35
+ requirement: &id002 !ruby/object:Gem::Requirement
36
+ none: false
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ segments:
41
+ - 0
42
+ version: "0"
43
+ type: :development
44
+ prerelease: false
45
+ version_requirements: *id002
46
+ - !ruby/object:Gem::Dependency
47
+ name: bundler
48
+ requirement: &id003 !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ segments:
54
+ - 1
55
+ - 0
56
+ - 0
57
+ version: 1.0.0
58
+ type: :development
59
+ prerelease: false
60
+ version_requirements: *id003
61
+ - !ruby/object:Gem::Dependency
62
+ name: jeweler
63
+ requirement: &id004 !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ segments:
69
+ - 1
70
+ - 5
71
+ - 1
72
+ version: 1.5.1
73
+ type: :development
74
+ prerelease: false
75
+ version_requirements: *id004
76
+ - !ruby/object:Gem::Dependency
77
+ name: rcov
78
+ requirement: &id005 !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ segments:
84
+ - 0
85
+ version: "0"
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: *id005
89
+ - !ruby/object:Gem::Dependency
90
+ name: horo
91
+ requirement: &id006 !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ segments:
97
+ - 0
98
+ version: "0"
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *id006
102
+ - !ruby/object:Gem::Dependency
103
+ name: prawn
104
+ requirement: &id007 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ segments:
110
+ - 0
111
+ version: "0"
112
+ type: :runtime
113
+ prerelease: false
114
+ version_requirements: *id007
115
+ description: Easily create PDF invoices
116
+ email: drewtemp@gmail.com
117
+ executables: []
118
+
119
+ extensions: []
120
+
121
+ extra_rdoc_files:
122
+ - LICENSE.txt
123
+ - README.rdoc
124
+ files:
125
+ - Rakefile
126
+ - init.rb
127
+ - lib/generators/standard.rb
128
+ - lib/invoice/helpers.rb
129
+ - lib/invoice/invoice.rb
130
+ - lib/invoice/line_item.rb
131
+ - lib/invoicepdf.rb
132
+ - LICENSE.txt
133
+ - README.rdoc
134
+ - test/helper.rb
135
+ - test/test_invoice.rb
136
+ has_rdoc: true
137
+ homepage: http://github.com/drewtempelmeyer/invoicepdf
138
+ licenses:
139
+ - MIT
140
+ post_install_message:
141
+ rdoc_options: []
142
+
143
+ require_paths:
144
+ - lib
145
+ required_ruby_version: !ruby/object:Gem::Requirement
146
+ none: false
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ hash: 419636474764141488
151
+ segments:
152
+ - 0
153
+ version: "0"
154
+ required_rubygems_version: !ruby/object:Gem::Requirement
155
+ none: false
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ segments:
160
+ - 0
161
+ version: "0"
162
+ requirements: []
163
+
164
+ rubyforge_project: invoicepdf
165
+ rubygems_version: 1.3.7
166
+ signing_key:
167
+ specification_version: 3
168
+ summary: Easily create PDF invoices
169
+ test_files:
170
+ - test/helper.rb
171
+ - test/test_invoice.rb