payday 1.0.0beta7 → 1.0.0beta8
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.
- data/README.md +1 -37
- data/lib/payday/i18n.rb +1 -1
- data/lib/payday/invoice.rb +9 -2
- data/lib/payday/invoiceable.rb +12 -2
- data/lib/payday/locale/de.yml +19 -0
- data/lib/payday/locale/en.yml +1 -0
- data/lib/payday/locale/es.yml +19 -0
- data/lib/payday/locale/fr.yml +19 -0
- data/lib/payday/pdf_renderer.rb +19 -8
- data/lib/payday/version.rb +1 -1
- data/test/invoice_test.rb +7 -3
- metadata +5 -2
data/README.md
CHANGED
@@ -45,43 +45,7 @@ Using Payday with ActiveRecord Objects (or any other objects, for that matter)
|
|
45
45
|
|
46
46
|
Payday focuses on two main objects, an invoice and a line item, so to use Payday with ActiveRecord you'll want to create your own classes for those objects. We include the Payday::Invoiceable and Payday::LineItemable modules to help out with that.
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
In a new migration:
|
51
|
-
|
52
|
-
create_table :invoices do |t|
|
53
|
-
# invoices will work without anything but bill_to, but there are quite a few options for the fields you can save, like ship_to
|
54
|
-
# due_at, and paid_at
|
55
|
-
t.string :bill_to
|
56
|
-
|
57
|
-
t.timestamps
|
58
|
-
end
|
59
|
-
|
60
|
-
create_table :line_items do |t|
|
61
|
-
t.decimal :price
|
62
|
-
t.string :description
|
63
|
-
t.integer :quantity # can also be :decimal or :float - just needs to be numeric
|
64
|
-
|
65
|
-
t.integer :invoice_id
|
66
|
-
|
67
|
-
t.timestamps
|
68
|
-
end
|
69
|
-
|
70
|
-
In app/models/invoice.rb:
|
71
|
-
|
72
|
-
class Invoice < ActiveRecord::Base
|
73
|
-
include Payday::Invoiceable
|
74
|
-
|
75
|
-
has_many :line_items
|
76
|
-
end
|
77
|
-
|
78
|
-
In app/models/line_item.rb:
|
79
|
-
|
80
|
-
class LineItem < ActiveRecord::Base
|
81
|
-
include Payday::LineItemable
|
82
|
-
|
83
|
-
belongs_to :invoice
|
84
|
-
end
|
48
|
+
Thanks to the work of Andrew Nordman, Payday includes a Rails generator that makes it super simple to generate the necessary models and migration for wiring Payday up to your app. Run `rails generate payday:setup --help` for more information about using the generator.
|
85
49
|
|
86
50
|
For a bit more fleshed out example, be sure to check out [http://github.com/commondream/payday-example](http://github.com/commondream/payday-example).
|
87
51
|
|
data/lib/payday/i18n.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
# Load everything in the local folder
|
2
|
-
I18n.load_path.concat(Dir[File.join(File.dirname(__FILE__), "
|
2
|
+
I18n.load_path.concat(Dir[File.join(File.dirname(__FILE__), "locale", "*.yml")])
|
data/lib/payday/invoice.rb
CHANGED
@@ -4,8 +4,8 @@ module Payday
|
|
4
4
|
class Invoice
|
5
5
|
include Payday::Invoiceable
|
6
6
|
|
7
|
-
attr_accessor :invoice_number, :bill_to, :ship_to, :notes, :line_items, :
|
8
|
-
|
7
|
+
attr_accessor :invoice_number, :bill_to, :ship_to, :notes, :line_items, :shipping_rate, :shipping_description,
|
8
|
+
:tax_rate, :tax_description, :due_at, :paid_at, :currency, :invoice_details
|
9
9
|
|
10
10
|
def initialize(options = {})
|
11
11
|
self.invoice_number = options[:invoice_number] || nil
|
@@ -13,6 +13,8 @@ module Payday
|
|
13
13
|
self.ship_to = options[:ship_to] || nil
|
14
14
|
self.notes = options[:notes] || nil
|
15
15
|
self.line_items = options[:line_items] || []
|
16
|
+
self.shipping_rate = options[:shipping_rate] || nil
|
17
|
+
self.shipping_description = options[:shipping_description] || nil
|
16
18
|
self.tax_rate = options[:tax_rate] || nil
|
17
19
|
self.tax_description = options[:tax_description] || nil
|
18
20
|
self.due_at = options[:due_at] || nil
|
@@ -25,5 +27,10 @@ module Payday
|
|
25
27
|
def tax_rate=(value)
|
26
28
|
@tax_rate = BigDecimal.new(value.to_s)
|
27
29
|
end
|
30
|
+
|
31
|
+
# Shipping rate
|
32
|
+
def shipping_rate=(value)
|
33
|
+
@shipping_rate = BigDecimal.new(value.to_s)
|
34
|
+
end
|
28
35
|
end
|
29
36
|
end
|
data/lib/payday/invoiceable.rb
CHANGED
@@ -35,9 +35,19 @@ module Payday::Invoiceable
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
+
# TODO Add a per weight unit shipping cost
|
39
|
+
# Calculates the shipping
|
40
|
+
def shipping
|
41
|
+
if defined?(shipping_rate)
|
42
|
+
shipping_rate
|
43
|
+
else
|
44
|
+
0
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
38
48
|
# Calculates the total for this invoice.
|
39
49
|
def total
|
40
|
-
subtotal + tax
|
50
|
+
subtotal + tax + shipping
|
41
51
|
end
|
42
52
|
|
43
53
|
def overdue?
|
@@ -61,7 +71,7 @@ module Payday::Invoiceable
|
|
61
71
|
# Iterates through the details on this invoiceable. The block given should accept
|
62
72
|
# two parameters, the detail name and the actual detail value.
|
63
73
|
def each_detail(&block)
|
64
|
-
return if
|
74
|
+
return if defined?(invoice_details).nil?
|
65
75
|
|
66
76
|
invoice_details.each do |detail|
|
67
77
|
block.call(detail[0], detail[1])
|
@@ -0,0 +1,19 @@
|
|
1
|
+
de:
|
2
|
+
payday:
|
3
|
+
status:
|
4
|
+
overdue: ÜBERFÄLLIG
|
5
|
+
paid: BEZAHLT
|
6
|
+
invoice:
|
7
|
+
bill_to: Rechnung an
|
8
|
+
due_date: "Fälligkeit:"
|
9
|
+
invoice_no: "Rechnungsnr.:"
|
10
|
+
paid_date: "Zahlungsdatum:"
|
11
|
+
ship_to: Versenden an
|
12
|
+
subtotal: "Zwischensumme:"
|
13
|
+
tax: "Steuern:"
|
14
|
+
total: "Gesamt:"
|
15
|
+
line_item:
|
16
|
+
amount: Betrag
|
17
|
+
description: Beschreibung
|
18
|
+
quantity: Menge
|
19
|
+
unit_price: Stückpreis
|
data/lib/payday/locale/en.yml
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
es:
|
2
|
+
payday:
|
3
|
+
status:
|
4
|
+
overdue: RETRASADO
|
5
|
+
paid: PAGADO
|
6
|
+
invoice:
|
7
|
+
bill_to: Facturar a
|
8
|
+
due_date: "Vencimiento:"
|
9
|
+
invoice_no: "Recibo #:"
|
10
|
+
paid_date: "Pagado en:"
|
11
|
+
ship_to: Enviar a
|
12
|
+
subtotal: "Subtotal:"
|
13
|
+
tax: "Impuesto:"
|
14
|
+
total: "Total:"
|
15
|
+
line_item:
|
16
|
+
amount: Cantidad
|
17
|
+
description: Descripción
|
18
|
+
quantity: Cantidad
|
19
|
+
unit_price: Precio por Unidad
|
@@ -0,0 +1,19 @@
|
|
1
|
+
fr:
|
2
|
+
payday:
|
3
|
+
status:
|
4
|
+
paid: PAYÉ
|
5
|
+
overdue: EN RETARD
|
6
|
+
invoice:
|
7
|
+
bill_to: Facturé à
|
8
|
+
ship_to: Livré à
|
9
|
+
invoice_no: "Facture #:"
|
10
|
+
due_date: "Paiment dû le:"
|
11
|
+
paid_date: "Payé le:"
|
12
|
+
subtotal: "Sous-total:"
|
13
|
+
tax: "Taxe:"
|
14
|
+
total: "Total:"
|
15
|
+
line_item:
|
16
|
+
description: Description
|
17
|
+
unit_price: Prix unitaire
|
18
|
+
quantity: Quantité
|
19
|
+
amount: Montant
|
data/lib/payday/pdf_renderer.rb
CHANGED
@@ -28,6 +28,8 @@ module Payday
|
|
28
28
|
line_items_table(invoice, pdf)
|
29
29
|
totals_lines(invoice, pdf)
|
30
30
|
notes(invoice, pdf)
|
31
|
+
|
32
|
+
page_numbers(pdf)
|
31
33
|
|
32
34
|
pdf
|
33
35
|
end
|
@@ -41,7 +43,7 @@ module Payday
|
|
41
43
|
end
|
42
44
|
|
43
45
|
if stamp
|
44
|
-
pdf.bounding_box([
|
46
|
+
pdf.bounding_box([150, pdf.cursor - 50], :width => pdf.bounds.width - 300) do
|
45
47
|
pdf.font("Helvetica-Bold") do
|
46
48
|
pdf.fill_color "cc0000"
|
47
49
|
pdf.text stamp, :align=> :center, :size => 25, :rotate => 15
|
@@ -171,8 +173,16 @@ module Payday
|
|
171
173
|
table_data = []
|
172
174
|
table_data << [bold_cell(pdf, I18n.t('payday.invoice.subtotal', :default => "Subtotal:")),
|
173
175
|
cell(pdf, number_to_currency(invoice.subtotal, invoice), :align => :right)]
|
174
|
-
|
175
|
-
|
176
|
+
if invoice.tax_rate > 0
|
177
|
+
table_data << [bold_cell(pdf,
|
178
|
+
invoice.tax_description.nil? ? I18n.t('payday.invoice.tax', :default => "Tax:") : invoice.tax_description),
|
179
|
+
cell(pdf, number_to_currency(invoice.tax, invoice), :align => :right)]
|
180
|
+
end
|
181
|
+
if invoice.shipping_rate > 0
|
182
|
+
table_data << [bold_cell(pdf,
|
183
|
+
invoice.shipping_description.nil? ? I18n.t('payday.invoice.shipping', :default => "Shipping:") : invoice.shipping_description),
|
184
|
+
cell(pdf, number_to_currency(invoice.shipping, invoice), :align => :right)]
|
185
|
+
end
|
176
186
|
table_data << [bold_cell(pdf, I18n.t('payday.invoice.total', :default => "Total:"), :size => 12),
|
177
187
|
cell(pdf, number_to_currency(invoice.total, invoice), :size => 12, :align => :right)]
|
178
188
|
table = pdf.make_table(table_data, :cell_style => { :borders => [] })
|
@@ -195,6 +205,12 @@ module Payday
|
|
195
205
|
end
|
196
206
|
end
|
197
207
|
|
208
|
+
def self.page_numbers(pdf)
|
209
|
+
if pdf.page_count > 1
|
210
|
+
pdf.number_pages("<page> / <total>", [pdf.bounds.right - 18, -15])
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
198
214
|
def self.invoice_or_default(invoice, property)
|
199
215
|
if invoice.respond_to?(property) && invoice.send(property)
|
200
216
|
invoice.send(property)
|
@@ -212,11 +228,6 @@ module Payday
|
|
212
228
|
cell(pdf, text, options)
|
213
229
|
end
|
214
230
|
|
215
|
-
# from Rails, I think
|
216
|
-
def self.number_with_delimiter(number, delimiter=",")
|
217
|
-
number.to_s.gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}")
|
218
|
-
end
|
219
|
-
|
220
231
|
# Converts this number to a formatted currency string
|
221
232
|
def self.number_to_currency(number, invoice)
|
222
233
|
number.to_money(invoice_or_default(invoice, :currency)).format
|
data/lib/payday/version.rb
CHANGED
data/test/invoice_test.rb
CHANGED
@@ -7,14 +7,17 @@ module Payday
|
|
7
7
|
i = Invoice.new(:invoice_number => 20, :bill_to => "Here", :ship_to => "There",
|
8
8
|
:notes => "These are some notes.",
|
9
9
|
:line_items => [LineItem.new(:price => 10, :quantity => 3, :description => "Shirts")],
|
10
|
-
:
|
10
|
+
:shipping_rate => 15.00, :shipping_description => "USPS Priority Mail:",
|
11
|
+
:tax_rate => 0.125, :tax_description => "Local Sales Tax, 12.5%")
|
11
12
|
|
12
13
|
assert_equal 20, i.invoice_number
|
13
14
|
assert_equal "Here", i.bill_to
|
14
15
|
assert_equal "There", i.ship_to
|
15
16
|
assert_equal "These are some notes.", i.notes
|
16
17
|
assert_equal "Shirts", i.line_items[0].description
|
17
|
-
assert_equal BigDecimal.new("
|
18
|
+
assert_equal BigDecimal.new("15.00"), i.shipping_rate
|
19
|
+
assert_equal "USPS Priority Mail:", i.shipping_description
|
20
|
+
assert_equal BigDecimal.new("0.125"), i.tax_rate
|
18
21
|
assert_equal "Local Sales Tax, 12.5%", i.tax_description
|
19
22
|
end
|
20
23
|
|
@@ -116,7 +119,7 @@ module Payday
|
|
116
119
|
assert !File.exists?("tmp/testing.pdf")
|
117
120
|
|
118
121
|
i = Invoice.new(:tax_rate => 0.1, :notes => "These are some crazy awesome notes!", :invoice_number => 12,
|
119
|
-
:due_at => Date.civil(2011, 1, 22),
|
122
|
+
:due_at => Date.civil(2011, 1, 22), #:paid_at => Date.civil(2012, 2, 22),
|
120
123
|
:bill_to => "Alan Johnson\n101 This Way\nSomewhere, SC 22222",
|
121
124
|
:ship_to => "Frank Johnson\n101 That Way\nOther, SC 22229",
|
122
125
|
:invoice_details => {"Ordered By:" => "Alan Johnson", "Paid By:" => "Dude McDude"})
|
@@ -130,6 +133,7 @@ module Payday
|
|
130
133
|
end
|
131
134
|
|
132
135
|
i.render_pdf_to_file("tmp/testing.pdf")
|
136
|
+
|
133
137
|
assert File.exists?("tmp/testing.pdf")
|
134
138
|
end
|
135
139
|
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: payday
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease: 5
|
5
|
-
version: 1.0.
|
5
|
+
version: 1.0.0beta8
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Alan Johnson
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-03-
|
13
|
+
date: 2011-03-14 00:00:00 -04:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -84,7 +84,10 @@ files:
|
|
84
84
|
- lib/payday/invoiceable.rb
|
85
85
|
- lib/payday/line_item.rb
|
86
86
|
- lib/payday/line_itemable.rb
|
87
|
+
- lib/payday/locale/de.yml
|
87
88
|
- lib/payday/locale/en.yml
|
89
|
+
- lib/payday/locale/es.yml
|
90
|
+
- lib/payday/locale/fr.yml
|
88
91
|
- lib/payday/pdf_renderer.rb
|
89
92
|
- lib/payday/version.rb
|
90
93
|
- payday.gemspec
|