uomi 0.2.15 → 0.2.16

Sign up to get free protection for your applications and to get access to all the features.
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