uomi 0.2.15 → 0.2.16

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 CHANGED
@@ -4,8 +4,9 @@ source "http://rubygems.org"
4
4
  gemspec
5
5
 
6
6
  group :development do
7
- gem 'rspec'
8
- gem 'rspec-rails'
7
+ gem 'rspec', '2.8.0'
8
+ gem 'rspec-rails', '2.8.1'
9
9
  gem 'sqlite3'
10
10
  gem 'database_cleaner', '>= 1.2.0'
11
+ gem 'andand'
11
12
  end
@@ -9,18 +9,21 @@ module Uomi
9
9
  end
10
10
 
11
11
  def self.generate_invoice(&block)
12
- invoice = Invoice.new
13
- invoice.instance_eval(&block)
14
- invoice.save!
15
- invoice
12
+ ActiveRecord::Base.transaction do
13
+ invoice = Invoice.new
14
+ invoice.instance_eval(&block)
15
+ invoice.save!
16
+ invoice
17
+ end
16
18
  end
17
19
 
18
20
  def self.generate_credit_note(&block)
19
- credit_note = CreditNote.new
20
- credit_note.instance_eval(&block)
21
- credit_note.save!
22
- credit_note.issue!
23
- credit_note
21
+ ActiveRecord::Base.transaction do
22
+ credit_note = CreditNote.new
23
+ credit_note.instance_eval(&block)
24
+ credit_note.save!
25
+ credit_note
26
+ end
24
27
  end
25
28
 
26
29
  end
@@ -2,21 +2,21 @@ module Uomi
2
2
  class CreditNote < Invoice
3
3
  alias_attribute :receipt_number, :invoice_number
4
4
 
5
- has_one :credit_note_invoice, dependent: :destroy
6
- has_one :invoice, through: :credit_note_invoice
5
+ has_many :credit_note_invoices, dependent: :destroy
6
+ has_many :invoices, through: :credit_note_invoices
7
7
  has_many :credit_note_credit_transactions, dependent: :destroy
8
8
 
9
9
  def issue(issued_at = Time.now)
10
10
  self.issued_at = issued_at
11
11
  create_initial_transaction!
12
- record_transaction_against_invoice!
12
+ record_transaction_against_invoice! unless self.invoices.blank?
13
13
  record_credit_notes!
14
+ record_transaction!
14
15
  end
15
16
 
16
17
  def record_transaction_against_invoice!
17
- raise RuntimeError, "You must allocate a credit note against an invoice" if invoice.blank?
18
- raise RuntimeError, "You must allocate a credit note against an issued invoice" unless invoice.issued?
19
-
18
+ invoice = invoices.first
19
+ validate(invoice: invoice, amount: self.total)
20
20
  invoice.add_credit_transaction(amount: total)
21
21
  invoice.save!
22
22
  CreditNoteCreditTransaction.create!(transaction: invoice.transactions.last, credit_note_id: self.id)
@@ -24,10 +24,10 @@ module Uomi
24
24
 
25
25
  def credit(options={})
26
26
  add_line_item(
27
- invoiceable: options[:line_item].invoiceable,
27
+ invoiceable: options[:line_item].andand.invoiceable,
28
28
  amount: options[:amount] || 0,
29
29
  tax: options[:tax] || 0,
30
- description: options[:description] || "Credit note against #{options[:line_item].description}" #?
30
+ description: options[:description] || "Credit note against #{options[:line_item].andand.description}" #?
31
31
  )
32
32
  end
33
33
 
@@ -35,11 +35,17 @@ module Uomi
35
35
  raise RuntimeError, "You must allocate a credit note against an invoice" if invoice.blank?
36
36
  raise RuntimeError, "You must allocate a credit note against an issued invoice" unless invoice.issued?
37
37
 
38
- self.credit_note_invoice = CreditNoteInvoice.new(invoice_id: invoice.id)
38
+ self.credit_note_invoices << CreditNoteInvoice.new(invoice_id: invoice.id)
39
39
  self.buyer = invoice.buyer
40
40
  self.seller = invoice.seller
41
41
  end
42
42
 
43
+ def record_transaction!
44
+ unless self.invoices.blank?
45
+ add_debit_transaction(amount: total)
46
+ end
47
+ end
48
+
43
49
  def record_credit_notes!
44
50
  line_items.each do |line_item|
45
51
  invoiceable = line_item.invoiceable
@@ -66,5 +72,30 @@ module Uomi
66
72
 
67
73
  save!
68
74
  end
75
+
76
+ def validate(options={})
77
+ raise RuntimeError, "You must allocate this credit against an invoice" if options[:invoice].blank?
78
+ raise RuntimeError, "You must allocate this credit against a Uomi Invoice" unless options[:invoice].is_a?(Uomi::Invoice)
79
+ raise RuntimeError, "You cannot allocate nothing to the invoice" if (options[:amount].blank? || options[:amount].zero?)
80
+ end
81
+
82
+ # Refund section
83
+
84
+ def refund(&block)
85
+ instance_eval(&block)
86
+ save!
87
+ end
88
+
89
+ def set_balance_off(options={})
90
+ validate(options)
91
+ invoice = options[:invoice]
92
+
93
+ invoice.add_credit_transaction(amount: options[:amount])
94
+ against_invoice(invoice)
95
+ invoice.save!
96
+
97
+ self.add_debit_transaction(amount: options[:amount])
98
+ CreditNoteCreditTransaction.create!(transaction: invoice.transactions.last, credit_note_id: self.id)
99
+ end
69
100
  end
70
101
  end
@@ -1,3 +1,3 @@
1
1
  module Uomi
2
- VERSION = "0.2.15"
2
+ VERSION = "0.2.16"
3
3
  end
@@ -60,11 +60,9 @@ describe Uomi::CreditNote do
60
60
  against_invoice invoice
61
61
  end
62
62
 
63
- @invoice.reload
64
- end
63
+ @credit_note.issue!
65
64
 
66
- it "should be issued" do
67
- @credit_note.should be_issued
65
+ @invoice.reload
68
66
  end
69
67
 
70
68
  it "should have a receipt number" do
@@ -81,7 +79,7 @@ describe Uomi::CreditNote do
81
79
  end
82
80
 
83
81
  it "should know if it is linked to an invoice" do
84
- @credit_note.invoice.should == @invoice
82
+ @credit_note.invoices.should == [@invoice]
85
83
  end
86
84
 
87
85
  it "should be linked to the credit transaction paid against the invoice" do
@@ -103,6 +101,124 @@ describe Uomi::CreditNote do
103
101
  @credit_note.seller.sellerable.should == @invoice_seller
104
102
  end
105
103
 
104
+ it "should set the balance to 0 if applied against an invoice" do
105
+ @credit_note.balance.should == 0
106
+ end
107
+
108
+ it "should mark the credit note as settled" do
109
+ @credit_note.should be_settled
110
+ end
111
+
112
+ end
113
+
114
+ context "Ad Hoc Credit Note not applied to any invoices" do
115
+ before(:each) do
116
+ @credit_note = Uomi::generate_credit_note do
117
+ credit amount: 5000, description: 'Description'
118
+ credit amount: 2000, description: 'Another Description'
119
+ end
120
+ @credit_note.issue!
121
+ end
122
+
123
+ it "should generate a credit note to the value of 70.00" do
124
+ @credit_note.total.should == 7000
125
+ end
126
+
127
+ it "should have a balance of 70.00" do
128
+ @credit_note.balance.should == 7000
129
+ end
130
+
131
+ context "Applying credit note to multiple invoices" do
132
+ before(:each) do
133
+ @invoice1 = Uomi::generate_invoice do
134
+ line_item description: "Line Item 1", amount: 5000, line_item_type_id: 1
135
+ end
136
+ @invoice1.issue!
137
+
138
+ @invoice2 = Uomi::generate_invoice do
139
+ line_item description: "Line Item 1", amount: 2000, line_item_type_id: 1
140
+ end
141
+ @invoice2.issue!
142
+ end
143
+
144
+ context "Apply credit to invoice 1 and 2" do
145
+ before(:each) do
146
+ inv = @invoice1
147
+
148
+ @credit_note.refund do
149
+ set_balance_off invoice: inv, amount: 5000
150
+ end
151
+
152
+ @credit_note.reload
153
+ @invoice1.reload
154
+ end
155
+
156
+ it "should set a credit note against an invoice" do
157
+ @invoice1.credit_notes.should == [@credit_note]
158
+ end
159
+
160
+ it "should settle the invoice" do
161
+ @invoice1.should be_settled
162
+ end
163
+
164
+ it "should set the balance on the credit note to 20" do
165
+ @credit_note.balance.should == 2000
166
+ end
167
+
168
+ it "should have created a debit transaction on the credit note to the value of 50.00" do
169
+ @credit_note.debit_transactions.last.amount.should == 5000
170
+ end
171
+
172
+ it "should have created a credit transaction against the invoice for 50.00" do
173
+ @invoice1.credit_transactions.last.amount.should == 5000
174
+ end
175
+
176
+ it "should know which invoice the credit note has transacted against" do
177
+ t = @credit_note.credit_note_credit_transactions.last
178
+ t.transaction.invoice.should == @invoice1
179
+ end
180
+
181
+ context "apply 20-00 to invoice 2" do
182
+ before(:each) do
183
+ inv = @invoice2
184
+
185
+ @credit_note.refund do
186
+ set_balance_off invoice: inv, amount: 2000
187
+ end
188
+
189
+ @credit_note.reload
190
+ @invoice2.reload
191
+ end
192
+
193
+ it "should set a credit note against an invoice1 and invoice 2" do
194
+ @invoice1.credit_notes.should == [@credit_note]
195
+ @invoice2.credit_notes.should == [@credit_note]
196
+ end
197
+
198
+ it "should settle the invoice" do
199
+ @invoice2.should be_settled
200
+ end
201
+
202
+ it "should settle the credit note" do
203
+ @credit_note.balance.should == 0
204
+ @credit_note.should be_settled
205
+ end
206
+
207
+ it "should have created a debit transaction on the credit note to the value of 50.00" do
208
+ @credit_note.debit_transactions.last.amount.should == 2000
209
+ end
210
+
211
+ it "should have created a credit transaction against the invoice for 50.00" do
212
+ @invoice2.credit_transactions.last.amount.should == 2000
213
+ end
214
+
215
+ it "should know which invoice the credit note has transacted against" do
216
+ t = @credit_note.credit_note_credit_transactions.last
217
+ t.transaction.invoice.should == @invoice2
218
+ end
219
+ end
220
+ end
221
+ end
106
222
  end
107
223
 
108
224
  context "When applying credits to the invoiceables" do
@@ -119,19 +235,6 @@ describe Uomi::CreditNote do
119
235
  end
120
236
 
121
237
  end
122
-
123
- context "trying to create a standalone credit note" do
124
-
125
- it "should raise an error if no invoice is specified" do
126
- expect {Uomi::generate_credit_note do
127
- line_items.each do |line_item|
128
- credit amount: 500, description: "Credit note for Line Item #{line_item.id}", tax: 0
129
- end
130
- decorate_with tenant_name: "Peter"
131
- end}.to raise_error(RuntimeError, "You must allocate a credit note against an invoice")
132
- end
133
- end
134
-
135
238
  end
136
239
 
137
240
  end
@@ -22,6 +22,7 @@ Gem::Specification.new do |s|
22
22
  s.add_dependency "activerecord", "~> 3.0"
23
23
  s.add_dependency "i18n"
24
24
  s.add_dependency "workflow", '= 0.8.7'
25
+ s.add_dependency "andand"
25
26
 
26
27
  s.add_development_dependency 'combustion', '~> 0.3.1'
27
28
  s.add_development_dependency 'database_cleaner', '~> 1.2.0'
metadata CHANGED
@@ -1,121 +1,132 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: uomi
3
- version: !ruby/object:Gem::Version
4
- version: 0.2.15
5
- prerelease:
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 2
8
+ - 16
9
+ version: 0.2.16
6
10
  platform: ruby
7
- authors:
11
+ authors:
8
12
  - Douglas Anderson
9
13
  - Jeffrey van Aswegen
10
14
  autorequire:
11
15
  bindir: bin
12
16
  cert_chain: []
13
- date: 2014-04-09 00:00:00.000000000 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
17
+
18
+ date: 2014-09-16 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
16
22
  name: activesupport
17
- requirement: !ruby/object:Gem::Requirement
18
- none: false
19
- requirements:
20
- - - ! '>='
21
- - !ruby/object:Gem::Version
22
- version: '0'
23
- type: :runtime
24
23
  prerelease: false
25
- version_requirements: !ruby/object:Gem::Requirement
24
+ requirement: &id001 !ruby/object:Gem::Requirement
26
25
  none: false
27
- requirements:
28
- - - ! '>='
29
- - !ruby/object:Gem::Version
30
- version: '0'
31
- - !ruby/object:Gem::Dependency
32
- name: activerecord
33
- requirement: !ruby/object:Gem::Requirement
34
- none: false
35
- requirements:
36
- - - ~>
37
- - !ruby/object:Gem::Version
38
- version: '3.0'
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ segments:
30
+ - 0
31
+ version: "0"
39
32
  type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: activerecord
40
36
  prerelease: false
41
- version_requirements: !ruby/object:Gem::Requirement
37
+ requirement: &id002 !ruby/object:Gem::Requirement
42
38
  none: false
43
- requirements:
39
+ requirements:
44
40
  - - ~>
45
- - !ruby/object:Gem::Version
46
- version: '3.0'
47
- - !ruby/object:Gem::Dependency
48
- name: i18n
49
- requirement: !ruby/object:Gem::Requirement
50
- none: false
51
- requirements:
52
- - - ! '>='
53
- - !ruby/object:Gem::Version
54
- version: '0'
41
+ - !ruby/object:Gem::Version
42
+ segments:
43
+ - 3
44
+ - 0
45
+ version: "3.0"
55
46
  type: :runtime
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: i18n
56
50
  prerelease: false
57
- version_requirements: !ruby/object:Gem::Requirement
51
+ requirement: &id003 !ruby/object:Gem::Requirement
58
52
  none: false
59
- requirements:
60
- - - ! '>='
61
- - !ruby/object:Gem::Version
62
- version: '0'
63
- - !ruby/object:Gem::Dependency
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ segments:
57
+ - 0
58
+ version: "0"
59
+ type: :runtime
60
+ version_requirements: *id003
61
+ - !ruby/object:Gem::Dependency
64
62
  name: workflow
65
- requirement: !ruby/object:Gem::Requirement
63
+ prerelease: false
64
+ requirement: &id004 !ruby/object:Gem::Requirement
66
65
  none: false
67
- requirements:
68
- - - '='
69
- - !ruby/object:Gem::Version
66
+ requirements:
67
+ - - "="
68
+ - !ruby/object:Gem::Version
69
+ segments:
70
+ - 0
71
+ - 8
72
+ - 7
70
73
  version: 0.8.7
71
74
  type: :runtime
75
+ version_requirements: *id004
76
+ - !ruby/object:Gem::Dependency
77
+ name: andand
72
78
  prerelease: false
73
- version_requirements: !ruby/object:Gem::Requirement
79
+ requirement: &id005 !ruby/object:Gem::Requirement
74
80
  none: false
75
- requirements:
76
- - - '='
77
- - !ruby/object:Gem::Version
78
- version: 0.8.7
79
- - !ruby/object:Gem::Dependency
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ segments:
85
+ - 0
86
+ version: "0"
87
+ type: :runtime
88
+ version_requirements: *id005
89
+ - !ruby/object:Gem::Dependency
80
90
  name: combustion
81
- requirement: !ruby/object:Gem::Requirement
82
- none: false
83
- requirements:
84
- - - ~>
85
- - !ruby/object:Gem::Version
86
- version: 0.3.1
87
- type: :development
88
91
  prerelease: false
89
- version_requirements: !ruby/object:Gem::Requirement
92
+ requirement: &id006 !ruby/object:Gem::Requirement
90
93
  none: false
91
- requirements:
94
+ requirements:
92
95
  - - ~>
93
- - !ruby/object:Gem::Version
96
+ - !ruby/object:Gem::Version
97
+ segments:
98
+ - 0
99
+ - 3
100
+ - 1
94
101
  version: 0.3.1
95
- - !ruby/object:Gem::Dependency
96
- name: database_cleaner
97
- requirement: !ruby/object:Gem::Requirement
98
- none: false
99
- requirements:
100
- - - ~>
101
- - !ruby/object:Gem::Version
102
- version: 1.2.0
103
102
  type: :development
103
+ version_requirements: *id006
104
+ - !ruby/object:Gem::Dependency
105
+ name: database_cleaner
104
106
  prerelease: false
105
- version_requirements: !ruby/object:Gem::Requirement
107
+ requirement: &id007 !ruby/object:Gem::Requirement
106
108
  none: false
107
- requirements:
109
+ requirements:
108
110
  - - ~>
109
- - !ruby/object:Gem::Version
111
+ - !ruby/object:Gem::Version
112
+ segments:
113
+ - 1
114
+ - 2
115
+ - 0
110
116
  version: 1.2.0
111
- description: ! ' Manage invoices. '
112
- email:
117
+ type: :development
118
+ version_requirements: *id007
119
+ description: " Manage invoices. "
120
+ email:
113
121
  - i.am.douglas.anderson@gmail.com
114
122
  - jeffmess@gmail.com
115
123
  executables: []
124
+
116
125
  extensions: []
126
+
117
127
  extra_rdoc_files: []
118
- files:
128
+
129
+ files:
119
130
  - .gitignore
120
131
  - .rvmrc
121
132
  - .travis.yml
@@ -158,31 +169,39 @@ files:
158
169
  - spec/lib/uomi/overdue_invoice_spec.rb
159
170
  - spec/spec_helper.rb
160
171
  - uomi.gemspec
172
+ has_rdoc: true
161
173
  homepage: https://github.com/tehtorq/invoicing
162
174
  licenses: []
175
+
163
176
  post_install_message:
164
177
  rdoc_options: []
165
- require_paths:
178
+
179
+ require_paths:
166
180
  - lib
167
- required_ruby_version: !ruby/object:Gem::Requirement
181
+ required_ruby_version: !ruby/object:Gem::Requirement
168
182
  none: false
169
- requirements:
170
- - - ! '>='
171
- - !ruby/object:Gem::Version
172
- version: '0'
173
- required_rubygems_version: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ segments:
187
+ - 0
188
+ version: "0"
189
+ required_rubygems_version: !ruby/object:Gem::Requirement
174
190
  none: false
175
- requirements:
176
- - - ! '>='
177
- - !ruby/object:Gem::Version
178
- version: '0'
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ segments:
195
+ - 0
196
+ version: "0"
179
197
  requirements: []
198
+
180
199
  rubyforge_project: uomi
181
- rubygems_version: 1.8.24
200
+ rubygems_version: 1.3.7.1
182
201
  signing_key:
183
202
  specification_version: 3
184
203
  summary: An uomi gem.
185
- test_files:
204
+ test_files:
186
205
  - spec/README
187
206
  - spec/internal/config/database.yml.sample
188
207
  - spec/internal/config/routes.rb