simple_invoice-emailer 0.0.1
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/Gemfile +2 -0
- data/Gemfile.lock +35 -0
- data/lib/simple_invoice/emailer/email_invoice_text_table.rb +108 -0
- data/lib/simple_invoice/emailer/mail_config.rb +46 -0
- data/lib/simple_invoice/emailer/mailer.rb +45 -0
- data/lib/simple_invoice/emailer/text_body.rb +67 -0
- data/lib/simple_invoice/emailer/text_list.rb +49 -0
- data/lib/simple_invoice/emailer.rb +18 -0
- data/simple_invoice-emailer.gemspec +21 -0
- data/spec/email_invoice_text_table_spec.rb +24 -0
- data/spec/mailer_spec.rb +50 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/text_body_spec.rb +50 -0
- data/spec/text_list_spec.rb +19 -0
- metadata +107 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
simple_invoice-emailer (0.0.0)
|
5
|
+
mail
|
6
|
+
text-table
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
diff-lcs (1.2.4)
|
12
|
+
mail (2.5.4)
|
13
|
+
mime-types (~> 1.16)
|
14
|
+
treetop (~> 1.4.8)
|
15
|
+
mime-types (1.25)
|
16
|
+
polyglot (0.3.3)
|
17
|
+
rspec (2.14.1)
|
18
|
+
rspec-core (~> 2.14.0)
|
19
|
+
rspec-expectations (~> 2.14.0)
|
20
|
+
rspec-mocks (~> 2.14.0)
|
21
|
+
rspec-core (2.14.5)
|
22
|
+
rspec-expectations (2.14.3)
|
23
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
24
|
+
rspec-mocks (2.14.3)
|
25
|
+
text-table (1.2.3)
|
26
|
+
treetop (1.4.15)
|
27
|
+
polyglot
|
28
|
+
polyglot (>= 0.3.1)
|
29
|
+
|
30
|
+
PLATFORMS
|
31
|
+
ruby
|
32
|
+
|
33
|
+
DEPENDENCIES
|
34
|
+
rspec
|
35
|
+
simple_invoice-emailer!
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'text-table'
|
2
|
+
|
3
|
+
module SimpleInvoice
|
4
|
+
module Emailer
|
5
|
+
class EmailInvoiceTextTable
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@table = Text::Table.new
|
9
|
+
@table.rows = []
|
10
|
+
@invoice_rows = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def line_item values
|
14
|
+
@invoice_rows << values.values_at(*[:description, :price, :quantity, :total]).collect(&:to_s)
|
15
|
+
end
|
16
|
+
|
17
|
+
def total total
|
18
|
+
@total = total
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [String]
|
22
|
+
def text_table
|
23
|
+
@table.head = left ['Description', 'Price', 'Quantity', 'Total']
|
24
|
+
set_column_alignments [:left, :right, :right, :right]
|
25
|
+
@invoice_rows.each do |row|
|
26
|
+
add_row row
|
27
|
+
end
|
28
|
+
@table.foot = [{:value => 'Total', :colspan => 3}, right(@total)]
|
29
|
+
@table
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_s
|
33
|
+
text_table.to_s
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def set_column_alignments alignments
|
39
|
+
@alignments = alignments
|
40
|
+
end
|
41
|
+
|
42
|
+
# @param row [Array<String>]
|
43
|
+
def add_row row
|
44
|
+
rows = rows_multi_line row
|
45
|
+
rows.each do |row|
|
46
|
+
@table.rows << row_with_alignments(row)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# @param row [Array<String>]
|
51
|
+
def rows_multi_line row
|
52
|
+
if (n = number_of_lines row) > 1
|
53
|
+
split_into_lines = row.collect do |value|
|
54
|
+
value.split("\n")
|
55
|
+
end
|
56
|
+
(0...n).collect do |index|
|
57
|
+
split_into_lines.collect do |lines|
|
58
|
+
lines[index]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
else
|
62
|
+
[row]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# @param row [Array<String>]
|
67
|
+
def number_of_lines row
|
68
|
+
row.collect do |value|
|
69
|
+
value.count "\n"
|
70
|
+
end.max + 1
|
71
|
+
end
|
72
|
+
|
73
|
+
# @param row [Array<String>]
|
74
|
+
# @return [Array<Hash>]
|
75
|
+
def row_with_alignments row
|
76
|
+
row.zip(@alignments).collect do |value, alignment|
|
77
|
+
align value, alignment
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# @param value [String]
|
82
|
+
# @return [Hash]
|
83
|
+
def left value
|
84
|
+
align value, :left
|
85
|
+
end
|
86
|
+
|
87
|
+
# @param value [String]
|
88
|
+
# @return [Hash]
|
89
|
+
def right value
|
90
|
+
align value, :right
|
91
|
+
end
|
92
|
+
|
93
|
+
# @param value [String, Array<String>]
|
94
|
+
# @param alignment [Symbol]
|
95
|
+
# @return [Hash, Array<Hash>]
|
96
|
+
def align value, alignment
|
97
|
+
if value.is_a? Array
|
98
|
+
value.collect do |val|
|
99
|
+
align val, alignment
|
100
|
+
end
|
101
|
+
else
|
102
|
+
{:value => value, :align => alignment}
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module SimpleInvoice
|
2
|
+
module Emailer
|
3
|
+
class MailConfig
|
4
|
+
|
5
|
+
class << self
|
6
|
+
|
7
|
+
extend Forwardable
|
8
|
+
def_delegator :instance, :[]
|
9
|
+
|
10
|
+
def instance
|
11
|
+
@instance ||= new
|
12
|
+
end
|
13
|
+
|
14
|
+
# @param email [String]
|
15
|
+
def email_from email
|
16
|
+
instance[:email_from] = email
|
17
|
+
end
|
18
|
+
|
19
|
+
# @param subject [#call]
|
20
|
+
def email_subject subject
|
21
|
+
instance[:email_subject] = subject
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param name [String]
|
25
|
+
def organisation_name name
|
26
|
+
instance[:organisation_name] = name
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize
|
32
|
+
@config_hash = {}
|
33
|
+
end
|
34
|
+
|
35
|
+
def [](key)
|
36
|
+
@config_hash[key]
|
37
|
+
end
|
38
|
+
|
39
|
+
def []=(key, value)
|
40
|
+
@config_hash[key] = value
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module SimpleInvoice
|
2
|
+
module Emailer
|
3
|
+
class Mailer
|
4
|
+
|
5
|
+
# @param mail_config [SimpleInvoice::Emailer::MailConfig]
|
6
|
+
def initialize mail_config=MailConfig
|
7
|
+
@mail_config = mail_config
|
8
|
+
end
|
9
|
+
|
10
|
+
# @param invoice [SimpleInvoice::Invoice]
|
11
|
+
def deliver! invoice
|
12
|
+
mail_instance(invoice).deliver
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def mail_instance invoice
|
18
|
+
_email_from = get_config(:email_from)
|
19
|
+
_email_subject = email_subject(invoice)
|
20
|
+
_email_body = email_body(invoice)
|
21
|
+
Mail.new do
|
22
|
+
to invoice.contact.email
|
23
|
+
from _email_from
|
24
|
+
subject _email_subject
|
25
|
+
body _email_body
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def email_body invoice
|
30
|
+
TextBody.new(invoice, @mail_config).email_body
|
31
|
+
end
|
32
|
+
|
33
|
+
def email_subject invoice
|
34
|
+
get_config(:email_subject)[invoice]
|
35
|
+
end
|
36
|
+
|
37
|
+
def get_config key
|
38
|
+
@mail_config[key].tap do |value|
|
39
|
+
raise "Missing config key #{key}" if value.nil?
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module SimpleInvoice
|
2
|
+
module Emailer
|
3
|
+
class TextBody
|
4
|
+
|
5
|
+
# @param invoice [SimpleInvoice::Invoice]
|
6
|
+
def initialize invoice, mail_config=MailConfig
|
7
|
+
@invoice = invoice
|
8
|
+
@mail_config = mail_config
|
9
|
+
end
|
10
|
+
|
11
|
+
# @return [String]
|
12
|
+
def email_body
|
13
|
+
salutation + "\n" +
|
14
|
+
"\n" +
|
15
|
+
preamble + "\n" +
|
16
|
+
"\n" +
|
17
|
+
invoice_data +
|
18
|
+
"\n" +
|
19
|
+
"Invoice Items:\n" +
|
20
|
+
line_items_table +
|
21
|
+
"\n" +
|
22
|
+
postscript + "\n"
|
23
|
+
end
|
24
|
+
|
25
|
+
def salutation
|
26
|
+
"Dear #{@invoice.contact.name}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def preamble
|
30
|
+
"This email is an invoice for services by #{@mail_config[:organisation_name]}."
|
31
|
+
end
|
32
|
+
|
33
|
+
def postscript
|
34
|
+
""
|
35
|
+
end
|
36
|
+
|
37
|
+
def invoice_data
|
38
|
+
list = TextList.new
|
39
|
+
list.add 'Invoice Number', @invoice.invoice_number
|
40
|
+
list.add 'Amount Due', dollars(@invoice.line_items.total)
|
41
|
+
list.add 'Due Date', @invoice.due_date
|
42
|
+
list.to_s
|
43
|
+
end
|
44
|
+
|
45
|
+
def line_items_table
|
46
|
+
table = EmailInvoiceTextTable.new
|
47
|
+
@invoice.line_items.to_a.each do |line_item|
|
48
|
+
table.line_item :description => line_item.description,
|
49
|
+
:price => dollars(line_item.price),
|
50
|
+
:quantity => line_item.quantity,
|
51
|
+
:total => dollars(line_item.total)
|
52
|
+
end
|
53
|
+
table.total dollars(@invoice.line_items.total)
|
54
|
+
table.to_s
|
55
|
+
end
|
56
|
+
|
57
|
+
# @param total_cents [Fixnum]
|
58
|
+
# @return [String]
|
59
|
+
def dollars total_cents
|
60
|
+
dollar = total_cents / 100
|
61
|
+
cents = total_cents % 100
|
62
|
+
"$%d.%02d" % [dollar, cents]
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'text-table'
|
2
|
+
|
3
|
+
module SimpleInvoice
|
4
|
+
module Emailer
|
5
|
+
class TextList
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@table = Text::Table.new :horizontal_padding => 1,
|
9
|
+
:vertical_boundary => ' ',
|
10
|
+
:horizontal_boundary => ' ',
|
11
|
+
:boundary_intersection => ' '
|
12
|
+
@table.rows = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def add label, value
|
16
|
+
@table.rows << [{:value => "#{label}:", :align => :right}, value.to_s]
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
reduce_gap(unindent(remove_empty_lines(@table.to_s))) + "\n"
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def remove_empty_lines str
|
26
|
+
str.gsub(/\n\s+\n/, "\n").gsub(/^\s+\n/, "")
|
27
|
+
end
|
28
|
+
|
29
|
+
# also removes trailing spaces from each line
|
30
|
+
def unindent str
|
31
|
+
lines = str.split("\n")
|
32
|
+
spaces = minimum_leading_spaces lines
|
33
|
+
lines.collect do |line|
|
34
|
+
line.slice(spaces, line.length).rstrip
|
35
|
+
end.join("\n")
|
36
|
+
end
|
37
|
+
|
38
|
+
def minimum_leading_spaces lines
|
39
|
+
lines.collect do |line|
|
40
|
+
/^\s+/.match(line).to_s.length
|
41
|
+
end.min
|
42
|
+
end
|
43
|
+
|
44
|
+
def reduce_gap str
|
45
|
+
str.gsub(': ', ': ')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'mail'
|
2
|
+
|
3
|
+
module SimpleInvoice
|
4
|
+
module Emailer
|
5
|
+
|
6
|
+
autoload :TextBody, "simple_invoice/emailer/text_body"
|
7
|
+
autoload :EmailInvoiceTextTable, "simple_invoice/emailer/email_invoice_text_table"
|
8
|
+
autoload :TextList, "simple_invoice/emailer/text_list"
|
9
|
+
autoload :Mailer, "simple_invoice/emailer/mailer"
|
10
|
+
autoload :MailConfig, "simple_invoice/emailer/mail_config"
|
11
|
+
|
12
|
+
# @param invoice [SimpleInvoice::Invoice]
|
13
|
+
def self.deliver! invoice
|
14
|
+
Mailer.new.deliver! invoice
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "simple_invoice-emailer"
|
6
|
+
s.version = "0.0.1"
|
7
|
+
s.authors = ["Joel Plane"]
|
8
|
+
s.email = ["joel.plane@gmail.com"]
|
9
|
+
s.homepage = "https://github.com/joelplane/simple_invoice-emailer"
|
10
|
+
s.summary = %q{emailer for SimpleInvoice}
|
11
|
+
s.description = %q{sends SimpleInvoices via email}
|
12
|
+
|
13
|
+
s.files = `git ls-files`.split("\n")
|
14
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
15
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
|
18
|
+
s.add_dependency "text-table"
|
19
|
+
s.add_dependency "mail"
|
20
|
+
s.add_development_dependency "rspec"
|
21
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module SimpleInvoice::Emailer
|
4
|
+
describe EmailInvoiceTextTable do
|
5
|
+
|
6
|
+
example do
|
7
|
+
expected_output =
|
8
|
+
"+-------------+--------+----------+---------+\n" \
|
9
|
+
"| Description | Price | Quantity | Total |\n" \
|
10
|
+
"+-------------+--------+----------+---------+\n" \
|
11
|
+
"| Gardening | $50.00 | 1 | $50.00 |\n" \
|
12
|
+
"| Lawn Mowing | $60.00 | 1 | $60.00 |\n" \
|
13
|
+
"+-------------+--------+----------+---------+\n" \
|
14
|
+
"| Total | $110.00 |\n" \
|
15
|
+
"+-------------+--------+----------+---------+\n"
|
16
|
+
table = EmailInvoiceTextTable.new
|
17
|
+
table.line_item :description => 'Gardening', :price => "$50.00", :quantity => 1, :total => "$50.00"
|
18
|
+
table.line_item :description => 'Lawn Mowing', :price => "$60.00", :quantity => 1, :total => "$60.00"
|
19
|
+
table.total "$110.00"
|
20
|
+
table.to_s.should == expected_output
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
data/spec/mailer_spec.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
module SimpleInvoice::Emailer
|
2
|
+
describe Mailer do
|
3
|
+
|
4
|
+
let :mail_config do
|
5
|
+
email_subject = lambda do |invoice|
|
6
|
+
"Invoice ##{invoice.invoice_number}"
|
7
|
+
end
|
8
|
+
{
|
9
|
+
:email_subject => email_subject,
|
10
|
+
:email_from => 'accounts@example.com'
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
let :contact do
|
15
|
+
double 'contact', :name => "John Smith", :email => 'john.smith@customer.example.com'
|
16
|
+
end
|
17
|
+
|
18
|
+
let :line_items do
|
19
|
+
double 'line_items', :total => 110_00,
|
20
|
+
:to_a => [
|
21
|
+
double('line_item', :description => 'Gardening', :price => 50_00, :quantity => 1, :total => 50_00),
|
22
|
+
double('line_item', :description => 'Lawn Mowing', :price => 60_00, :quantity => 1, :total => 50_00)
|
23
|
+
]
|
24
|
+
end
|
25
|
+
|
26
|
+
let :invoice do
|
27
|
+
double 'invoice', :invoice_number => 123456,
|
28
|
+
:issue_date => "2013-01-02",
|
29
|
+
:due_date => "2013-01-09",
|
30
|
+
:contact => contact,
|
31
|
+
:line_items => line_items
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
subject do
|
36
|
+
Mailer.new(mail_config).tap do |mailer|
|
37
|
+
mailer.stub(:email_body => 'body')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
example do
|
42
|
+
mail = subject.send(:mail_instance, invoice)
|
43
|
+
mail.should be_a Mail::Message
|
44
|
+
mail.subject.should == 'Invoice #123456'
|
45
|
+
mail.body.should == 'body'
|
46
|
+
mail.from.should == ['accounts@example.com']
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module SimpleInvoice::Emailer
|
4
|
+
describe TextBody do
|
5
|
+
|
6
|
+
let(:contact) do
|
7
|
+
double 'contact', :name => "John Smith"
|
8
|
+
end
|
9
|
+
let(:line_items) do
|
10
|
+
double 'line_items', :total => 110_00,
|
11
|
+
:to_a => [
|
12
|
+
double('line_item', :description => 'Gardening', :price => 50_00, :quantity => 1, :total => 50_00),
|
13
|
+
double('line_item', :description => 'Lawn Mowing', :price => 60_00, :quantity => 1, :total => 50_00)
|
14
|
+
]
|
15
|
+
end
|
16
|
+
let(:invoice) do
|
17
|
+
double 'invoice', :invoice_number => 123456,
|
18
|
+
:issue_date => "2013-01-02",
|
19
|
+
:due_date => "2013-01-09",
|
20
|
+
:contact => contact,
|
21
|
+
:line_items => line_items
|
22
|
+
end
|
23
|
+
let(:mail_config) do
|
24
|
+
{:organisation_name => "Business"}
|
25
|
+
end
|
26
|
+
|
27
|
+
example do
|
28
|
+
expected_output =
|
29
|
+
"Dear John Smith\n" \
|
30
|
+
"\n" \
|
31
|
+
"This email is an invoice for services by Business.\n" \
|
32
|
+
"\n" \
|
33
|
+
"Invoice Number: 123456\n" \
|
34
|
+
" Amount Due: $110.00\n" \
|
35
|
+
" Due Date: 2013-01-09\n" \
|
36
|
+
"\n" \
|
37
|
+
"Invoice Items:\n" \
|
38
|
+
"+-------------+--------+----------+---------+\n" \
|
39
|
+
"| Description | Price | Quantity | Total |\n" \
|
40
|
+
"+-------------+--------+----------+---------+\n" \
|
41
|
+
"| Gardening | $50.00 | 1 | $50.00 |\n" \
|
42
|
+
"| Lawn Mowing | $60.00 | 1 | $50.00 |\n" \
|
43
|
+
"+-------------+--------+----------+---------+\n" \
|
44
|
+
"| Total | $110.00 |\n" \
|
45
|
+
"+-------------+--------+----------+---------+"
|
46
|
+
SimpleInvoice::Emailer::TextBody.new(invoice, mail_config).email_body.strip.should == expected_output
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module SimpleInvoice::Emailer
|
4
|
+
describe TextList do
|
5
|
+
|
6
|
+
example do
|
7
|
+
expected_output =
|
8
|
+
"Invoice Number: 123456\n" \
|
9
|
+
" Amount Due: $1,100.00\n" \
|
10
|
+
" Due Date: 2013-01-01\n"
|
11
|
+
list = TextList.new
|
12
|
+
list.add 'Invoice Number', 123456
|
13
|
+
list.add 'Amount Due', '$1,100.00'
|
14
|
+
list.add 'Due Date', '2013-01-01'
|
15
|
+
list.to_s.should == expected_output
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: simple_invoice-emailer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Joel Plane
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-11-10 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: text-table
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: mail
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
description: sends SimpleInvoices via email
|
63
|
+
email:
|
64
|
+
- joel.plane@gmail.com
|
65
|
+
executables: []
|
66
|
+
extensions: []
|
67
|
+
extra_rdoc_files: []
|
68
|
+
files:
|
69
|
+
- Gemfile
|
70
|
+
- Gemfile.lock
|
71
|
+
- lib/simple_invoice/emailer.rb
|
72
|
+
- lib/simple_invoice/emailer/email_invoice_text_table.rb
|
73
|
+
- lib/simple_invoice/emailer/mail_config.rb
|
74
|
+
- lib/simple_invoice/emailer/mailer.rb
|
75
|
+
- lib/simple_invoice/emailer/text_body.rb
|
76
|
+
- lib/simple_invoice/emailer/text_list.rb
|
77
|
+
- simple_invoice-emailer.gemspec
|
78
|
+
- spec/email_invoice_text_table_spec.rb
|
79
|
+
- spec/mailer_spec.rb
|
80
|
+
- spec/spec_helper.rb
|
81
|
+
- spec/text_body_spec.rb
|
82
|
+
- spec/text_list_spec.rb
|
83
|
+
homepage: https://github.com/joelplane/simple_invoice-emailer
|
84
|
+
licenses: []
|
85
|
+
post_install_message:
|
86
|
+
rdoc_options: []
|
87
|
+
require_paths:
|
88
|
+
- lib
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - ! '>='
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
|
+
none: false
|
97
|
+
requirements:
|
98
|
+
- - ! '>='
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0'
|
101
|
+
requirements: []
|
102
|
+
rubyforge_project:
|
103
|
+
rubygems_version: 1.8.24
|
104
|
+
signing_key:
|
105
|
+
specification_version: 3
|
106
|
+
summary: emailer for SimpleInvoice
|
107
|
+
test_files: []
|