simple_invoice 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.
Files changed (50) hide show
  1. data/.gitignore +2 -0
  2. data/Gemfile +2 -0
  3. data/example/Gemfile +2 -0
  4. data/example/create_invoice_from_subscription.expected-output.txt +12 -0
  5. data/example/create_invoice_from_subscription.rb +15 -0
  6. data/example/create_one_off_invoice.expected-output.txt +13 -0
  7. data/example/create_one_off_invoice.rb +19 -0
  8. data/example/lib/example_subscriptions/gardening_subscription.rb +13 -0
  9. data/example/lib/example_subscriptions/lawn_mowing_subscription.rb +13 -0
  10. data/example/lib/invoice_number_allocator.rb +15 -0
  11. data/example/lib/invoice_plain_text_formatter.rb +61 -0
  12. data/example/run_daily_process_subscriptions.expected-output.txt +14 -0
  13. data/example/run_daily_process_subscriptions.rb +27 -0
  14. data/git-hooks/INSTALL.sh +11 -0
  15. data/git-hooks/pre-commit.sh +15 -0
  16. data/lib/simple_invoice.rb +14 -0
  17. data/lib/simple_invoice/billing_period.rb +40 -0
  18. data/lib/simple_invoice/billing_period_type.rb +44 -0
  19. data/lib/simple_invoice/billing_period_type/monthly.rb +12 -0
  20. data/lib/simple_invoice/billing_period_type/weekly.rb +12 -0
  21. data/lib/simple_invoice/config.rb +33 -0
  22. data/lib/simple_invoice/contact.rb +5 -0
  23. data/lib/simple_invoice/invoice.rb +22 -0
  24. data/lib/simple_invoice/invoice_data.rb +48 -0
  25. data/lib/simple_invoice/invoice_template.rb +15 -0
  26. data/lib/simple_invoice/line_item.rb +10 -0
  27. data/lib/simple_invoice/line_items.rb +40 -0
  28. data/lib/simple_invoice/services.rb +10 -0
  29. data/lib/simple_invoice/services/allocate_invoice_number.rb +33 -0
  30. data/lib/simple_invoice/services/create_invoice.rb +50 -0
  31. data/lib/simple_invoice/services/create_invoice_for_subscription.rb +53 -0
  32. data/lib/simple_invoice/services/create_invoice_template.rb +33 -0
  33. data/lib/simple_invoice/services/process_subscription.rb +62 -0
  34. data/lib/simple_invoice/services/process_subscriptions.rb +16 -0
  35. data/lib/simple_invoice/subscription.rb +26 -0
  36. data/lib/simple_invoice/version.rb +3 -0
  37. data/simple_invoice.gemspec +20 -0
  38. data/spec/model/billing_period_spec.rb +28 -0
  39. data/spec/model/billing_period_type_monthly_spec.rb +77 -0
  40. data/spec/model/billing_period_type_weekly_spec.rb +71 -0
  41. data/spec/model/invoice_data_spec.rb +45 -0
  42. data/spec/model/line_item_spec.rb +15 -0
  43. data/spec/model/line_items_spec.rb +15 -0
  44. data/spec/model/subscription_spec.rb +28 -0
  45. data/spec/services/create_invoice_for_subscription_spec.rb +52 -0
  46. data/spec/services/process_subscription_spec.rb +42 -0
  47. data/spec/spec_helper.rb +8 -0
  48. data/test-examples.rb +23 -0
  49. data/test.sh +4 -0
  50. metadata +110 -0
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+
3
+ module SimpleInvoice
4
+ describe BillingPeriodType::Monthly do
5
+
6
+ context "monthly" do
7
+ subject { BillingPeriodType::Monthly.new 1 }
8
+
9
+ describe "#last_day_of_period" do
10
+ specify do
11
+ {
12
+ '2012-02-01' => '2012-02-29',
13
+ '2013-02-01' => '2013-02-28',
14
+ '2013-09-01' => '2013-09-30',
15
+ '2013-10-01' => '2013-10-31',
16
+ '2013-12-01' => '2013-12-31'
17
+ }.each do |first_day, last_day|
18
+ subject.last_day_of_period(Date.parse(first_day)).should == Date.parse(last_day)
19
+ end
20
+ end
21
+ end
22
+
23
+ describe "#first_day_of_next_period" do
24
+ specify do
25
+ {
26
+ '2012-02-01' => '2012-03-01',
27
+ '2013-02-01' => '2013-03-01',
28
+ '2013-09-01' => '2013-10-01',
29
+ '2013-10-01' => '2013-11-01',
30
+ '2013-12-01' => '2014-01-01'
31
+ }.each do |first_day, last_day|
32
+ subject.first_day_of_next_period(Date.parse(first_day)).should == Date.parse(last_day)
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ context "quarterly" do
39
+ subject { BillingPeriodType::Monthly.new 3 }
40
+
41
+ describe "#last_day_of_period" do
42
+ specify do
43
+ {
44
+ '2011-12-01' => '2012-02-29',
45
+ '2012-12-01' => '2013-02-28',
46
+ '2012-02-01' => '2012-04-30',
47
+ '2013-02-01' => '2013-04-30',
48
+ '2013-09-01' => '2013-11-30',
49
+ '2013-10-01' => '2013-12-31',
50
+ '2013-12-01' => '2014-02-28',
51
+ '2013-06-18' => '2013-09-17'
52
+ }.each do |first_day, last_day|
53
+ subject.last_day_of_period(Date.parse(first_day)).should == Date.parse(last_day)
54
+ end
55
+ end
56
+ end
57
+
58
+ describe "#first_day_of_next_period" do
59
+ specify do
60
+ {
61
+ '2011-12-01' => '2012-03-01',
62
+ '2012-12-01' => '2013-03-01',
63
+ '2012-02-01' => '2012-05-01',
64
+ '2013-02-01' => '2013-05-01',
65
+ '2013-09-01' => '2013-12-01',
66
+ '2013-10-01' => '2014-01-01',
67
+ '2013-12-01' => '2014-03-01',
68
+ '2013-06-18' => '2013-09-18'
69
+ }.each do |first_day, last_day|
70
+ subject.first_day_of_next_period(Date.parse(first_day)).should == Date.parse(last_day)
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+ end
77
+ end
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+
3
+ module SimpleInvoice
4
+ describe BillingPeriodType::Weekly do
5
+
6
+ context "weekly" do
7
+ subject { BillingPeriodType::Weekly.new 1 }
8
+
9
+ describe "#last_day_of_period" do
10
+ specify do
11
+ {
12
+ '2012-02-27' => '2012-03-04',
13
+ '2013-02-27' => '2013-03-05',
14
+ '2013-09-01' => '2013-09-07',
15
+ '2013-10-27' => '2013-11-02',
16
+ '2013-12-27' => '2014-01-02'
17
+ }.each do |first_day, last_day|
18
+ subject.last_day_of_period(Date.parse(first_day)).should == Date.parse(last_day)
19
+ end
20
+ end
21
+ end
22
+
23
+ describe "#first_day_of_next_period" do
24
+ specify do
25
+ {
26
+ '2012-02-27' => '2012-03-05',
27
+ '2013-02-27' => '2013-03-06',
28
+ '2013-09-01' => '2013-09-08',
29
+ '2013-10-27' => '2013-11-03',
30
+ '2013-12-27' => '2014-01-03'
31
+ }.each do |first_day, last_day|
32
+ subject.first_day_of_next_period(Date.parse(first_day)).should == Date.parse(last_day)
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ context "fortnightly" do
39
+ subject { BillingPeriodType::Weekly.new 2 }
40
+
41
+ describe "#last_day_of_period" do
42
+ specify do
43
+ {
44
+ '2012-02-27' => '2012-03-11',
45
+ '2013-02-27' => '2013-03-12',
46
+ '2013-09-01' => '2013-09-14',
47
+ '2013-10-27' => '2013-11-09',
48
+ '2013-12-27' => '2014-01-09'
49
+ }.each do |first_day, last_day|
50
+ subject.last_day_of_period(Date.parse(first_day)).should == Date.parse(last_day)
51
+ end
52
+ end
53
+ end
54
+
55
+ describe "#first_day_of_next_period" do
56
+ specify do
57
+ {
58
+ '2012-02-27' => '2012-03-12',
59
+ '2013-02-27' => '2013-03-13',
60
+ '2013-09-01' => '2013-09-15',
61
+ '2013-10-27' => '2013-11-10',
62
+ '2013-12-27' => '2014-01-10'
63
+ }.each do |first_day, last_day|
64
+ subject.first_day_of_next_period(Date.parse(first_day)).should == Date.parse(last_day)
65
+ end
66
+ end
67
+ end
68
+ end
69
+
70
+ end
71
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ module SimpleInvoice
4
+ describe InvoiceData do
5
+ subject { InvoiceData.new 'INV-123', '2013-09-01', '2013-09-08' }
6
+
7
+ describe "#invoice_number=" do
8
+ it "should store as a string" do
9
+ InvoiceData.new(123).invoice_number.should == '123'
10
+ end
11
+ end
12
+
13
+ describe "#set_dates" do
14
+ subject { InvoiceData.new 'INV-123' }
15
+ context "given dates as String" do
16
+ it "should parse date strings to Date" do
17
+ subject.set_dates '2013-09-01', '2013-09-08'
18
+ subject.issue_date.should == Date.parse('2013-09-01')
19
+ subject.due_date.should == Date.parse('2013-09-08')
20
+ end
21
+ end
22
+ context "given dates as Date" do
23
+ it "should accept dates as Date type" do
24
+ subject.set_dates Date.parse('2013-09-01'), Date.parse('2013-09-08')
25
+ subject.issue_date.should == Date.parse('2013-09-01')
26
+ subject.due_date.should == Date.parse('2013-09-08')
27
+ end
28
+ end
29
+ context "given due days instead of due_date" do
30
+ it "should interpret a Fixnum as due days" do
31
+ subject.set_dates '2013-09-01', 7
32
+ subject.issue_date.should == Date.parse('2013-09-01')
33
+ subject.due_date.should == Date.parse('2013-09-08')
34
+ end
35
+ end
36
+ end
37
+
38
+ describe "#due_days" do
39
+ it "should be the difference between the due date and issue date" do
40
+ subject.due_days.should be_a Fixnum
41
+ subject.due_days.should == 7
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ module SimpleInvoice
4
+ describe LineItem do
5
+
6
+ subject { LineItem.new "", 29_95, 2 }
7
+
8
+ describe "#total" do
9
+ it "sums line items" do
10
+ subject.total.should == 29_95 * 2
11
+ end
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ module SimpleInvoice
4
+ describe LineItems do
5
+
6
+ describe "#total" do
7
+ it "sums line items" do
8
+ subject.push double("line item 1", :total => 49_95)
9
+ subject.push double("line item 2", :total => 59_90)
10
+ subject.total.should == 49_95 + 59_90
11
+ end
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ module SimpleInvoice
4
+ describe Subscription do
5
+
6
+ subject do
7
+ Subscription.new.tap do |sub|
8
+ sub.start_date = Date.parse('2013-01-02')
9
+ sub.billing_period_type = :monthly
10
+ end
11
+ end
12
+
13
+ describe "#billing_periods" do
14
+ specify do
15
+ billing_periods = subject.billing_periods
16
+ [
17
+ '2013-01-02',
18
+ '2013-02-02',
19
+ '2013-03-02',
20
+ '2013-04-02'
21
+ ].each do |date|
22
+ billing_periods.next.first_day.should == Date.parse(date)
23
+ end
24
+ end
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+
3
+ module SimpleInvoice
4
+ describe Services::CreateInvoiceForSubscription do
5
+
6
+ let(:line_item_1) { LineItem.new "line item 1", 49_95, 1 }
7
+ let(:line_item_2) { LineItem.new "line item 2", 49_95, 2 }
8
+ let(:line_items) { LineItems.new [line_item_1, line_item_2]}
9
+ let(:template) do
10
+ double 'invoice_template', :line_items => line_items
11
+ end
12
+ let(:contact) { double('contact') }
13
+ let(:subscription) do
14
+ double 'subscription', :contact => contact,
15
+ :invoice_template => template,
16
+ :due_days => 7
17
+ end
18
+ let(:issue_date) { Date.parse('2013-10-01') }
19
+ subject do
20
+ Services::CreateInvoiceForSubscription.new(subscription, issue_date).tap do |inst|
21
+ inst.stub(:allocate_invoice_number => nil)
22
+ end
23
+ end
24
+
25
+ describe "#create_invoice" do
26
+ let(:invoice) { subject.create_invoice }
27
+ it "should produce an invoice" do
28
+ invoice.should be_a Invoice
29
+ end
30
+ it "should set issue date and due date" do
31
+ invoice.issue_date.should == issue_date
32
+ invoice.due_date.should == Date.parse('2013-10-08')
33
+ end
34
+ it "should set contact" do
35
+ invoice.contact.should == contact
36
+ end
37
+ it "should not set an invoice number" do
38
+ invoice.invoice_number.should be_nil
39
+ end
40
+ it "should add line items" do
41
+ invoice.line_items.length.should == 2
42
+ end
43
+ it "should copy line items" do
44
+ invoice.line_items.should_not equal line_items
45
+ line_item = invoice.line_items.to_a.first
46
+ line_item.should == line_item_1 # same value
47
+ line_item.should_not equal line_item_1 # different object
48
+ end
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ module SimpleInvoice
4
+ describe Services::ProcessSubscription do
5
+
6
+ let(:template) do
7
+ double 'invoice_template', :line_items => LineItems.new([])
8
+ end
9
+
10
+ def subscription
11
+ double 'subscription', :contact => nil,
12
+ :invoice_template => template,
13
+ :due_days => 7,
14
+ :start_date => Date.parse('2013-01-02'),
15
+ :billing_periods => ([
16
+ '2013-01-02',
17
+ '2013-02-02',
18
+ '2013-03-02',
19
+ '2013-04-02',
20
+ '2013-05-02',
21
+ '2013-06-02'
22
+ ].collect do |date|
23
+ double('billing_period', :first_day => Date.parse(date))
24
+ end).each #=> Enumerator
25
+ end
26
+
27
+ def call date
28
+ Services::ProcessSubscription.call date, subscription
29
+ end
30
+
31
+ specify do
32
+ call('2012-12-02').should be_nil
33
+ call('2013-01-01').should be_nil
34
+ call('2013-01-02').should be_a Invoice
35
+ call('2013-01-03').should be_nil
36
+ call('2013-02-01').should be_nil
37
+ call('2013-02-02').should be_a Invoice
38
+ call('2013-02-03').should be_nil
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,8 @@
1
+ require 'simple_invoice'
2
+
3
+ RSpec.configure do |config|
4
+ config.treat_symbols_as_metadata_keys_with_true_values = true
5
+ config.run_all_when_everything_filtered = true
6
+ config.filter_run :focus
7
+ config.order = 'random'
8
+ end
data/test-examples.rb ADDED
@@ -0,0 +1,23 @@
1
+ # bundle exec ruby test-examples.rb
2
+
3
+ failed = []
4
+
5
+ example_dir = File.expand_path('example', File.dirname(__FILE__))
6
+ Dir["#{example_dir}/*.expected-output.txt"].each do |output_file|
7
+ script_file = output_file.sub('.expected-output.txt', '.rb')
8
+ expected_output = File.read(output_file).strip
9
+ actual_output = `cd #{example_dir}; bundle exec ruby #{script_file}`.strip
10
+ if expected_output != actual_output
11
+ failed << script_file
12
+ end
13
+ end
14
+
15
+ if failed.any?
16
+ puts "Failed examples:"
17
+ failed.each do |script_file|
18
+ puts script_file
19
+ end
20
+ exit 1
21
+ else
22
+ exit 0
23
+ end
data/test.sh ADDED
@@ -0,0 +1,4 @@
1
+ #!/bin/sh
2
+
3
+ bundle exec rspec &&
4
+ bundle exec ruby test-examples.rb
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simple_invoice
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: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
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
+ description: Very simple invoice library with minimal dependencies
31
+ email:
32
+ - joel.plane@gmail.com
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - .gitignore
38
+ - Gemfile
39
+ - example/Gemfile
40
+ - example/create_invoice_from_subscription.expected-output.txt
41
+ - example/create_invoice_from_subscription.rb
42
+ - example/create_one_off_invoice.expected-output.txt
43
+ - example/create_one_off_invoice.rb
44
+ - example/lib/example_subscriptions/gardening_subscription.rb
45
+ - example/lib/example_subscriptions/lawn_mowing_subscription.rb
46
+ - example/lib/invoice_number_allocator.rb
47
+ - example/lib/invoice_plain_text_formatter.rb
48
+ - example/run_daily_process_subscriptions.expected-output.txt
49
+ - example/run_daily_process_subscriptions.rb
50
+ - git-hooks/INSTALL.sh
51
+ - git-hooks/pre-commit.sh
52
+ - lib/simple_invoice.rb
53
+ - lib/simple_invoice/billing_period.rb
54
+ - lib/simple_invoice/billing_period_type.rb
55
+ - lib/simple_invoice/billing_period_type/monthly.rb
56
+ - lib/simple_invoice/billing_period_type/weekly.rb
57
+ - lib/simple_invoice/config.rb
58
+ - lib/simple_invoice/contact.rb
59
+ - lib/simple_invoice/invoice.rb
60
+ - lib/simple_invoice/invoice_data.rb
61
+ - lib/simple_invoice/invoice_template.rb
62
+ - lib/simple_invoice/line_item.rb
63
+ - lib/simple_invoice/line_items.rb
64
+ - lib/simple_invoice/services.rb
65
+ - lib/simple_invoice/services/allocate_invoice_number.rb
66
+ - lib/simple_invoice/services/create_invoice.rb
67
+ - lib/simple_invoice/services/create_invoice_for_subscription.rb
68
+ - lib/simple_invoice/services/create_invoice_template.rb
69
+ - lib/simple_invoice/services/process_subscription.rb
70
+ - lib/simple_invoice/services/process_subscriptions.rb
71
+ - lib/simple_invoice/subscription.rb
72
+ - lib/simple_invoice/version.rb
73
+ - simple_invoice.gemspec
74
+ - spec/model/billing_period_spec.rb
75
+ - spec/model/billing_period_type_monthly_spec.rb
76
+ - spec/model/billing_period_type_weekly_spec.rb
77
+ - spec/model/invoice_data_spec.rb
78
+ - spec/model/line_item_spec.rb
79
+ - spec/model/line_items_spec.rb
80
+ - spec/model/subscription_spec.rb
81
+ - spec/services/create_invoice_for_subscription_spec.rb
82
+ - spec/services/process_subscription_spec.rb
83
+ - spec/spec_helper.rb
84
+ - test-examples.rb
85
+ - test.sh
86
+ homepage: https://github.com/joelplane/simple_invoice
87
+ licenses: []
88
+ post_install_message:
89
+ rdoc_options: []
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ! '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubyforge_project:
106
+ rubygems_version: 1.8.24
107
+ signing_key:
108
+ specification_version: 3
109
+ summary: simple invoice library
110
+ test_files: []