double_double 0.2.0 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -33,8 +33,8 @@ Edit the migration to match:
33
33
  class CreateDoubleDouble < ActiveRecord::Migration
34
34
  def change
35
35
  create_table :double_double_accounts do |t|
36
- t.string :name, null: false
37
36
  t.integer :number, null: false
37
+ t.string :name, null: false
38
38
  t.string :type, null: false
39
39
  t.boolean :contra, default: false
40
40
  end
@@ -42,31 +42,31 @@ class CreateDoubleDouble < ActiveRecord::Migration
42
42
 
43
43
  create_table :double_double_transactions do |t|
44
44
  t.string :description
45
+ t.references :initiator, polymorphic: true
45
46
  t.references :transaction_type
46
47
  t.timestamps
47
48
  end
49
+ add_index :double_double_transactions, :initiator_id
50
+ add_index :double_double_transactions, :initiator_type
48
51
  add_index :double_double_transactions, :transaction_type_id
49
52
 
50
53
  create_table :double_double_transaction_types do |t|
51
- t.integer :number, null: false
52
54
  t.string :description, null: false
53
55
  end
54
- add_index :double_double_transaction_types, :number
56
+ add_index :double_double_transaction_types, :description
55
57
 
56
58
  create_table :double_double_amounts do |t|
57
59
  t.string :type
58
60
  t.references :account
59
61
  t.references :transaction
60
- t.references :accountee, polymorphic: true
61
62
  t.references :context, polymorphic: true
62
- t.references :initiator, polymorphic: true
63
+ t.references :accountee, polymorphic: true
64
+
63
65
  t.integer :amount_cents, limit: 8, default: 0, null: false
64
66
  t.string :currency
65
67
  end
66
68
  add_index :double_double_amounts, :context_id
67
69
  add_index :double_double_amounts, :context_type
68
- add_index :double_double_amounts, :initiator_id
69
- add_index :double_double_amounts, :initiator_type
70
70
  add_index :double_double_amounts, :accountee_id
71
71
  add_index :double_double_amounts, :accountee_type
72
72
  add_index :double_double_amounts, :type
@@ -144,13 +144,15 @@ Contra accounts are used to offset a related account of the same class. *The ex
144
144
 
145
145
  #### Basic Scenario: We are creating a personal application to only track loan payments back to Grandpa.
146
146
 
147
- We've decided to keep things very simple and only create two accounts:
147
+ We've decided to keep things very simple and only create a few accounts:
148
148
  * 'Cash' an asset account.
149
149
  * 'Grandpa Loan' a liability account.
150
+ * 'Spending' an expense account
150
151
 
151
152
  ```ruby
152
153
  DoubleDouble::Asset.create! name:'Cash', number: 11
153
154
  DoubleDouble::Liability.create! name:'Grandpa Loan', number: 12
155
+ DoubleDouble::Expense.create! name:'Spending', number: 13
154
156
  ```
155
157
  Grandpa was kind enough to loan us $800 USD in cash for college textbooks. To enter this we will require a transaction which will affect both 'Cash' and 'Grandpa Loan'
156
158
  ```ruby
@@ -162,7 +164,23 @@ DoubleDouble::Transaction.create!(
162
164
  credits:[
163
165
  {account: 'Grandpa Loan', amount: '$800'}])
164
166
  ```
165
- But because we were surprised to have the option to buy a few used textbooks we can return some of Grandpa's loan. We will return $320.
167
+ We buy our college textbooks.
168
+
169
+ ```ruby
170
+ DoubleDouble::Transaction.create!(
171
+ description:
172
+ 'Purchase textbooks from bookstore',
173
+ debits:[
174
+ {account: 'Spending', amount: '$480'}],
175
+ credits:[
176
+ {account: 'Cash', amount: '$480'}])
177
+ ```
178
+ How much cash is left?
179
+
180
+ ```ruby
181
+ DoubleDouble::Account.named('Cash').balance.to_s # => "320.00"
182
+ ```
183
+ We deceided that we wanted to return $320 of the loan.
166
184
  ```ruby
167
185
  DoubleDouble::Transaction.create!(
168
186
  description:
@@ -172,10 +190,19 @@ DoubleDouble::Transaction.create!(
172
190
  credits:[
173
191
  {account: 'Cash', amount: '$320'}])
174
192
  ```
175
- If we want to know how much we still owed Grandpa we can look at the balance of the account.
193
+ How much do we still owe Grandpa?
176
194
  ```ruby
177
- DoubleDouble::Account.find_by_name('Grandpa Loan').balance.to_s # => "480.00"
195
+ DoubleDouble::Account.named('Grandpa Loan').balance.to_s # => "480.00"
178
196
  ```
197
+ How much did we spend?
198
+ ```ruby
199
+ DoubleDouble::Account.named('Spending').balance.to_s # => "480.00"
200
+ ```
201
+ How much cash do we have left?
202
+ ```ruby
203
+ DoubleDouble::Account.named('Cash').balance.to_s # => "0.00"
204
+ ```
205
+
179
206
 
180
207
  ### Realistic Scenarios
181
208
  * TODO: Write a realistic scenario
@@ -17,11 +17,13 @@ Gem::Specification.new do |gem|
17
17
  gem.test_files = gem.files.grep(%r{^(test|spec|features|account_types)/})
18
18
  gem.require_paths = ['lib']
19
19
 
20
- gem.add_dependency('money', '~> 5.1')
21
- gem.add_dependency('activerecord', '~> 3.2.11')
22
- gem.add_development_dependency('sqlite3')
23
- gem.add_development_dependency('rspec', '~> 2.12')
24
- gem.add_development_dependency('factory_girl')
25
- gem.add_development_dependency('database_cleaner')
26
- gem.add_development_dependency('pry')
20
+ gem.required_ruby_version = '>= 1.9.2'
21
+
22
+ gem.add_dependency 'money', '~> 5.1'
23
+ gem.add_dependency 'activerecord', '~> 3.2.11'
24
+ gem.add_development_dependency 'sqlite3'
25
+ gem.add_development_dependency 'rspec', '~> 2.12'
26
+ gem.add_development_dependency 'factory_girl'
27
+ gem.add_development_dependency 'database_cleaner'
28
+ gem.add_development_dependency 'pry'
27
29
  end
@@ -42,15 +42,30 @@ module DoubleDouble
42
42
  validates_uniqueness_of :name, :number
43
43
  validates_length_of :name, :minimum => 1
44
44
 
45
- def side_balance(is_debit, hash)
46
- a = is_debit ? DoubleDouble::DebitAmount.scoped : DoubleDouble::CreditAmount.scoped
47
- a = a.where(account_id: self.id)
48
- a = a.by_context(hash[:context]) if hash.has_key? :context
49
- a = a.by_initiator(hash[:initiator]) if hash.has_key? :initiator
50
- a = a.by_accountee(hash[:accountee]) if hash.has_key? :accountee
51
- Money.new(a.sum(:amount_cents))
45
+ class << self
46
+ # The trial balance of all accounts in the system. This should always equal zero,
47
+ # otherwise there is an error in the system.
48
+ #
49
+ # @return [Money] The value balance of all accounts
50
+ def trial_balance
51
+ raise(NoMethodError, "undefined method 'trial_balance'") unless self == DoubleDouble::Account
52
+ Asset.balance - (Liability.balance + Equity.balance + Revenue.balance - Expense.balance)
53
+ end
54
+
55
+ def balance
56
+ raise(NoMethodError, "undefined method 'balance'") if self == DoubleDouble::Account
57
+ accounts_balance = self.all.inject(Money.new(0)) {|sum, acct| acct.contra ? (sum - acct.balance) : (sum + acct.balance)}
58
+ end
59
+
60
+ def named account_name
61
+ self.where(name: account_name.to_s).first
62
+ end
63
+
64
+ def numbered account_number
65
+ self.where(number: account_number.to_i).first
66
+ end
52
67
  end
53
-
68
+
54
69
  def credits_balance(hash = {})
55
70
  side_balance(false, hash)
56
71
  end
@@ -59,30 +74,15 @@ module DoubleDouble
59
74
  side_balance(true, hash)
60
75
  end
61
76
 
62
- # The trial balance of all accounts in the system. This should always equal zero,
63
- # otherwise there is an error in the system.
64
- #
65
- # @return [Money] The value balance of all accounts
66
- def self.trial_balance
67
- raise(NoMethodError, "undefined method 'trial_balance'") unless self == DoubleDouble::Account
68
- Asset.balance - (Liability.balance + Equity.balance + Revenue.balance - Expense.balance)
69
- end
70
-
71
- def self.balance
72
- raise(NoMethodError, "undefined method 'balance'") if self == DoubleDouble::Account
73
- accounts_balance = Money.new(0)
74
- accounts = self.all
75
- accounts.each do |acct|
76
- if acct.contra
77
- accounts_balance -= acct.balance
78
- else
79
- accounts_balance += acct.balance
80
- end
81
- end
82
- accounts_balance
83
- end
84
-
85
77
  protected
78
+
79
+ def side_balance(is_debit, hash)
80
+ a = is_debit ? DoubleDouble::DebitAmount.scoped : DoubleDouble::CreditAmount.scoped
81
+ a = a.where(account_id: self.id)
82
+ a = a.by_context(hash[:context]) if hash.has_key? :context
83
+ a = a.by_accountee(hash[:accountee]) if hash.has_key? :accountee
84
+ Money.new(a.sum(:amount_cents))
85
+ end
86
86
  # The balance method that derived Accounts utilize.
87
87
  #
88
88
  # Nornal Debit Accounts:
@@ -13,13 +13,9 @@ module DoubleDouble
13
13
  belongs_to :account
14
14
  belongs_to :accountee, polymorphic: true
15
15
  belongs_to :context, polymorphic: true
16
- belongs_to :initiator, polymorphic: true
17
16
 
18
17
  scope :by_accountee, ->(a) { where(accountee_id: a.id, accountee_type: a.class.base_class) }
19
18
  scope :by_context, ->(c) { where(context_id: c.id, context_type: c.class.base_class) }
20
- scope :by_initiator, ->(i) { where(initiator_id: i.id, initiator_type: i.class.base_class) }
21
-
22
- # scope :by_transaction_type_number, -> {|tt_num| where( transaction: {transaction_type: {number: tt_num}})}
23
19
 
24
20
  validates_presence_of :type, :transaction, :account
25
21
  validates :amount_cents, numericality: {greater_than: 0}
@@ -7,8 +7,8 @@ module DoubleDouble
7
7
  # debit transactions
8
8
  #
9
9
  # @example
10
- # cash = DoubleDouble::Asset.find_by_name('Cash')
11
- # accounts_receivable = DoubleDouble::Asset.find_by_name('Accounts Receivable')
10
+ # cash = DoubleDouble::Asset.named('Cash')
11
+ # accounts_receivable = DoubleDouble::Asset.named('Accounts Receivable')
12
12
  #
13
13
  # debit_amount = DoubleDouble::DebitAmount.new(account: 'cash', amount: 1000)
14
14
  # credit_amount = DoubleDouble::CreditAmount.new(account: 'accounts_receivable', amount: 1000)
@@ -26,6 +26,7 @@ module DoubleDouble
26
26
  attr_accessible :description
27
27
 
28
28
  belongs_to :transaction_type
29
+ belongs_to :initiator, polymorphic: true
29
30
 
30
31
  has_many :credit_amounts
31
32
  has_many :debit_amounts
@@ -37,7 +38,8 @@ module DoubleDouble
37
38
  validate :has_debit_amounts?
38
39
  validate :amounts_cancel?
39
40
 
40
- scope :by_transaction_type_number, ->(tt_num) { where(transaction_type: {number: tt_num})}
41
+ scope :by_transaction_type, ->(tt) { where(transaction_type: tt)}
42
+ scope :by_initiator, ->(i) { where(initiator_id: i.id, initiator_type: i.class.base_class) }
41
43
 
42
44
  # Simple API for building a transaction and associated debit and credit amounts
43
45
  #
@@ -45,7 +47,7 @@ module DoubleDouble
45
47
  # transaction = DoubleDouble::Transaction.build(
46
48
  # description: "Sold some widgets",
47
49
  # debits: [
48
- # {account: "Accounts Receivable", amount: 50, context_id: 20, context_type: 'Job'}],
50
+ # {account: "Accounts Receivable", amount: 50, context: @some_active_record_object}],
49
51
  # credits: [
50
52
  # {account: "Sales Revenue", amount: 45},
51
53
  # {account: "Sales Tax Payable", amount: 5}])
@@ -55,7 +57,7 @@ module DoubleDouble
55
57
  t = Transaction.new()
56
58
  t.description = args[:description]
57
59
  t.transaction_type = args[:transaction_type] if args.has_key? :transaction_type
58
-
60
+ t.initiator = args[:initiator] if args.has_key? :initiator
59
61
  add_amounts_to_transaction(args[:debits], t, true)
60
62
  add_amounts_to_transaction(args[:credits], t, false)
61
63
  t
@@ -66,6 +68,10 @@ module DoubleDouble
66
68
  t.save!
67
69
  end
68
70
 
71
+ def transaction_type
72
+ self.transaction_type_id.nil? ? UnassignedTransactionType : TransactionType.find(self.transaction_type_id)
73
+ end
74
+
69
75
  private
70
76
 
71
77
  # Validation
@@ -102,10 +108,9 @@ module DoubleDouble
102
108
  end
103
109
 
104
110
  def self.prepare_amount_parameters args
105
- prepared_params = { account: Account.find_by_name(args[:account]), transaction: args[:transaction], amount: args[:amount]}
111
+ prepared_params = { account: Account.named(args[:account]), transaction: args[:transaction], amount: args[:amount]}
106
112
  prepared_params.merge!({accountee: args[:accountee]}) if args.has_key? :accountee
107
113
  prepared_params.merge!({context: args[:context]}) if args.has_key? :context
108
- prepared_params.merge!({initiator: args[:initiator]}) if args.has_key? :initiator
109
114
  prepared_params
110
115
  end
111
116
  end
@@ -3,9 +3,20 @@ module DoubleDouble
3
3
  self.table_name = 'double_double_transaction_types'
4
4
 
5
5
  has_many :transactions
6
- attr_accessible :number, :description
6
+ attr_accessible :description
7
7
 
8
- validates_numericality_of :number, greater_than: 0
9
- validates_length_of :description, minimum: 6
8
+ validates :description, length: { minimum: 6 }, presence: true, uniqueness: true
9
+
10
+ def self.of description_given
11
+ TransactionType.where(description: description_given.to_s).first
12
+ end
13
+ end
14
+
15
+ class UnassignedTransactionType
16
+ class << self
17
+ def description
18
+ 'unassigned'
19
+ end
20
+ end
10
21
  end
11
22
  end
@@ -1,3 +1,3 @@
1
1
  module DoubleDouble
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.3"
3
3
  end
@@ -62,7 +62,7 @@ module DoubleDouble
62
62
  description: 'spec transaction 05',
63
63
  debits: [{account: 'contra expense acct', amount: 333}],
64
64
  credits: [{account: 'contra revenue acct', amount: 333}])
65
- Account.trial_balance.should == 0
65
+ Account.trial_balance.should eq(0)
66
66
  end
67
67
  end
68
68
  end
@@ -63,6 +63,7 @@ module DoubleDouble
63
63
  @loan.credits_balance({context: @job}).should == Money.new(123 + 321)
64
64
  @loan.credits_balance({context: @po}).should == Money.new(275)
65
65
  @loan.credits_balance.should == Money.new(123 + 321 + 275 + 999)
66
+ Account.trial_balance.should eq(0)
66
67
  end
67
68
  end
68
69
  end
@@ -63,6 +63,7 @@ module DoubleDouble
63
63
  @cash.debits_balance({context: @job}).should == Money.new(123 + 321)
64
64
  @cash.debits_balance({context: @po}).should == Money.new(275)
65
65
  @cash.debits_balance.should == Money.new(123 + 321 + 275 + 999)
66
+ Account.trial_balance.should eq(0)
66
67
  end
67
68
  end
68
69
  end
@@ -4,24 +4,27 @@ module DoubleDouble
4
4
  before(:each) do
5
5
  @cash = DoubleDouble::Asset.create!(name:'Cash_11', number: 1011)
6
6
  @loan = DoubleDouble::Liability.create!(name:'Loan_12', number: 1012)
7
-
7
+ # dummy objects to stand-in for accountees
8
+ @user1 = DoubleDouble::Asset.create!(name:'some user1', number: 8991)
9
+ @user2 = DoubleDouble::Asset.create!(name:'some user2', number: 8992)
8
10
  # dummy objects to stand-in for a context
9
11
  @campaign1 = DoubleDouble::Asset.create!(name:'campaign_test1', number: 9991)
10
12
  @campaign2 = DoubleDouble::Asset.create!(name:'campaign_test2', number: 9992)
11
13
  end
12
14
 
13
- it 'should create a transaction using the create! method' do
15
+ it_behaves_like "it can run the README scenarios"
16
+
17
+ it 'should create a Transaction using the create! method' do
14
18
  -> {
15
19
  Transaction.create!(
16
20
  description: 'spec transaction 01',
17
21
  debits: [{account: 'Cash_11', amount: 10}],
18
22
  credits: [{account: 'Loan_12', amount: 9},
19
23
  {account: 'Loan_12', amount: 1}])
20
-
21
24
  }.should change(DoubleDouble::Transaction, :count).by(1)
22
25
  end
23
26
 
24
- it 'should not create a transaction using the build method' do
27
+ it 'should not create a Transaction using the build method' do
25
28
  -> {
26
29
  Transaction.build(
27
30
  description: 'spec transaction 01',
@@ -111,8 +114,52 @@ module DoubleDouble
111
114
  t.errors['base'].should == ['The credit and debit amounts are not equal']
112
115
  end
113
116
 
114
- describe 'context references' do
115
- it 'should allow a transaction to be built describing the context in the hash' do
117
+ describe 'transaction_types' do
118
+ it 'should create a Transaction with a TransactionType of Unassigned if none is passed in' do
119
+ t = Transaction.build(
120
+ description: 'spec transaction 01',
121
+ debits: [{account: 'Cash_11', amount: 10}],
122
+ credits: [{account: 'Loan_12', amount: 9},
123
+ {account: 'Loan_12', amount: 1}])
124
+ t.transaction_type.description.should eq('unassigned')
125
+ end
126
+
127
+ it 'should create a Transaction with a TransactionType of Unassigned if none is passed in' do
128
+ TransactionType.create!(description: 'donation')
129
+ t = Transaction.build(
130
+ description: 'spec transaction 01',
131
+ transaction_type: TransactionType.of(:donation),
132
+ debits: [{account: 'Cash_11', amount: 10}],
133
+ credits: [{account: 'Loan_12', amount: 9},
134
+ {account: 'Loan_12', amount: 1}])
135
+ t.transaction_type.description.should eq('donation')
136
+ end
137
+ end
138
+
139
+ describe 'amount accountee references' do
140
+ it 'should allow a Transaction to be built describing the accountee in the hash' do
141
+ Transaction.create!(
142
+ description: 'Sold some widgets',
143
+ debits: [{account: 'Cash_11', amount: 60, context: @campaign1, accountee: @user1},
144
+ {account: 'Cash_11', amount: 40, context: @campaign2, accountee: @user1},
145
+ {account: 'Cash_11', amount: 4, context: @campaign2, accountee: @user2}],
146
+ credits: [{account: 'Loan_12', amount: 45},
147
+ {account: 'Loan_12', amount: 9},
148
+ {account: 'Loan_12', amount: 50, context: @campaign1}])
149
+ Amount.by_accountee(@user1).count.should eq(2)
150
+ Amount.by_accountee(@user2).count.should eq(1)
151
+
152
+ @cash.debits_balance(context: @campaign1, accountee: @user1).should eq(60)
153
+ @cash.debits_balance(context: @campaign1, accountee: @user2).should eq(0)
154
+ @cash.debits_balance(context: @campaign2, accountee: @user1).should eq(40)
155
+ @cash.debits_balance(context: @campaign2, accountee: @user2).should eq(4)
156
+ @cash.debits_balance(context: @campaign2).should eq(44)
157
+ Account.trial_balance.should eq(0)
158
+ end
159
+ end
160
+
161
+ describe 'amount context references' do
162
+ it 'should allow a Transaction to be built describing the context in the hash' do
116
163
  Transaction.create!(
117
164
  description: 'Sold some widgets',
118
165
  debits: [{account: 'Cash_11', amount: 60, context: @campaign1},
@@ -122,34 +169,11 @@ module DoubleDouble
122
169
  {account: 'Loan_12', amount: 50, context: @campaign1}])
123
170
  Amount.by_context(@campaign1).count.should eq(2)
124
171
  Amount.by_context(@campaign2).count.should eq(1)
172
+
125
173
  @cash.debits_balance(context: @campaign1).should eq(60)
126
174
  @cash.debits_balance(context: @campaign2).should eq(40)
175
+ Account.trial_balance.should eq(0)
127
176
  end
128
177
  end
129
-
130
- describe 'README.md scenarios' do
131
- it 'should perform BASIC SCENARIO A correctly' do
132
- DoubleDouble::Asset.create! name:'Cash', number: 11
133
- DoubleDouble::Liability.create! name:'Grandpa Loan', number: 12
134
- # Grandpa was kind enough to loan us $800 USD in cash for college textbooks. To enter this we will require a transaction which will affect both 'Cash' and 'Grandpa Loan'
135
- DoubleDouble::Transaction.create!(
136
- description:
137
- 'We received a loan from Grandpa',
138
- debits:[
139
- {account: 'Cash', amount: '$800'}],
140
- credits:[
141
- {account: 'Grandpa Loan', amount: '$800'}])
142
- # But say that we wanted to return $320 because we were able to purchase a few used books.
143
- DoubleDouble::Transaction.create!(
144
- description:
145
- 'Payed back $320 to Grandpa',
146
- debits:[
147
- {account: 'Grandpa Loan', amount: '$320'}],
148
- credits:[
149
- {account: 'Cash', amount: '$320'}])
150
- # If we wanted to know how much we still owed Grandpa, we could look at the balance of the account.
151
- DoubleDouble::Account.find_by_name('Grandpa Loan').balance.to_s.should eq("480.00")
152
- end
153
- end
154
178
  end
155
179
  end
@@ -0,0 +1,26 @@
1
+ module DoubleDouble
2
+ describe TransactionType do
3
+
4
+ it 'should create a TransactionType using the create! method' do
5
+ -> {
6
+ TransactionType.create!(description: '123456')
7
+ }.should change(DoubleDouble::TransactionType, :count).by(1)
8
+ end
9
+
10
+ it 'should not be valid without a description' do
11
+ -> {
12
+ TransactionType.create!(description: '')
13
+ }.should raise_error(ActiveRecord::RecordInvalid)
14
+ t = TransactionType.new(description: '')
15
+ t.should_not be_valid
16
+ end
17
+
18
+ it 'should not be valid without a long-enough description' do
19
+ -> {
20
+ TransactionType.create!(description: '12345')
21
+ }.should raise_error(ActiveRecord::RecordInvalid)
22
+ t = TransactionType.new(description: '12345')
23
+ t.should_not be_valid
24
+ end
25
+ end
26
+ end
data/spec/spec_helper.rb CHANGED
@@ -19,23 +19,24 @@ ActiveRecord::Migration.verbose = false
19
19
 
20
20
  create_table :double_double_transactions do |t|
21
21
  t.string :description
22
+ t.references :initiator, polymorphic: true
22
23
  t.references :transaction_type
23
24
  t.timestamps
24
25
  end
26
+ add_index :double_double_transactions, :initiator_id
27
+ add_index :double_double_transactions, :initiator_type
25
28
  add_index :double_double_transactions, :transaction_type_id
26
29
 
27
30
  create_table :double_double_transaction_types do |t|
28
- t.integer :number, null: false
29
31
  t.string :description, null: false
30
32
  end
31
- add_index :double_double_transaction_types, :number
33
+ add_index :double_double_transaction_types, :description
32
34
 
33
35
  create_table :double_double_amounts do |t|
34
36
  t.string :type
35
37
  t.references :account
36
38
  t.references :transaction
37
39
  t.references :context, polymorphic: true
38
- t.references :initiator, polymorphic: true
39
40
  t.references :accountee, polymorphic: true
40
41
 
41
42
  t.integer :amount_cents, limit: 8, default: 0, null: false
@@ -43,8 +44,6 @@ ActiveRecord::Migration.verbose = false
43
44
  end
44
45
  add_index :double_double_amounts, :context_id
45
46
  add_index :double_double_amounts, :context_type
46
- add_index :double_double_amounts, :initiator_id
47
- add_index :double_double_amounts, :initiator_type
48
47
  add_index :double_double_amounts, :accountee_id
49
48
  add_index :double_double_amounts, :accountee_type
50
49
  add_index :double_double_amounts, :type
@@ -1,124 +1,128 @@
1
1
  # Liability, Equity, and Revenue account types
2
2
  shared_examples "a normal credit account type" do
3
3
  describe "<<" do
4
+
5
+ describe "basic behavior" do
6
+
7
+ before(:each) do
8
+ @acct1 = FactoryGirl.create(normal_credit_account_type, name: 'acct1')
9
+ @acct2_contra = FactoryGirl.create(normal_credit_account_type, name: 'acct2_contra', :contra => true)
10
+ @other_account = FactoryGirl.create("not_#{normal_credit_account_type}".to_sym, name: 'other_account')
11
+ end
4
12
 
5
- it "should report a NEGATIVE balance when an account is debited" do
6
- account = FactoryGirl.create(normal_credit_account_type)
7
- contra_account = FactoryGirl.create(normal_credit_account_type, :contra => true)
8
- t = FactoryGirl.build(:transaction)
9
- t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: 75, account: account)
10
- t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: 75, account: contra_account)
11
- t.save
12
- account.balance.should < 0
13
- contra_account.balance.should < 0
14
- end
13
+ it "should report a NEGATIVE balance when an account is debited" do
14
+ DoubleDouble::Transaction.create!(
15
+ description: 'Sold some widgets',
16
+ debits: [{account: 'acct1', amount: Money.new(75)}],
17
+ credits: [{account: 'acct2_contra', amount: Money.new(75)}])
18
+ @acct1.balance.should < 0
19
+ @acct2_contra.balance.should < 0
20
+ end
15
21
 
16
- it "should report a POSITIVE balance when an account is credited" do
17
- account = FactoryGirl.create(normal_credit_account_type)
18
- contra_account = FactoryGirl.create(normal_credit_account_type, :contra => true)
19
- t = FactoryGirl.build(:transaction)
20
- t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: 75, account: account)
21
- t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: 75, account: contra_account)
22
- t.save
23
- account.balance.should > 0
24
- contra_account.balance.should > 0
25
- end
22
+ it "should report a POSITIVE balance when an account is credited" do
23
+ DoubleDouble::Transaction.create!(
24
+ description: 'Sold some widgets',
25
+ debits: [{account: 'acct2_contra', amount: Money.new(75)}],
26
+ credits: [{account: 'acct1', amount: Money.new(75)}])
27
+ @acct1.balance.should > 0
28
+ @acct2_contra.balance.should > 0
29
+ end
26
30
 
27
- it "should report a POSITIVE balance across the account type when CREDITED
28
- and using an unrelated type for the balanced side transaction" do
29
- account = FactoryGirl.create(normal_credit_account_type)
30
- other_account = FactoryGirl.create("not_#{normal_credit_account_type}".to_sym)
31
- t = FactoryGirl.build(:transaction)
32
- t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: 50, account: account)
33
- t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: 50, account: other_account)
34
- t.save
35
- DoubleDouble.const_get(normal_credit_account_type.to_s.capitalize).should respond_to(:balance)
36
- DoubleDouble.const_get(normal_credit_account_type.to_s.capitalize).balance.should > 0
37
- DoubleDouble.const_get(normal_credit_account_type.to_s.capitalize).balance.should be_kind_of(Money)
38
- end
31
+ it "should report a POSITIVE balance across the account type when CREDITED
32
+ and using an unrelated type for the balanced side transaction" do
33
+ DoubleDouble::Transaction.create!(
34
+ description: 'Sold some widgets',
35
+ debits: [{account: 'other_account', amount: Money.new(50)}],
36
+ credits: [{account: 'acct1', amount: Money.new(50)}])
37
+ DoubleDouble.const_get(normal_credit_account_type.to_s.capitalize).should respond_to(:balance)
38
+ DoubleDouble.const_get(normal_credit_account_type.to_s.capitalize).balance.should > 0
39
+ DoubleDouble.const_get(normal_credit_account_type.to_s.capitalize).balance.should be_kind_of(Money)
40
+ end
39
41
 
40
- it "should report a NEGATIVE balance across the account type when DEBITED
41
- and using an unrelated type for the balanced side transaction" do
42
- account = FactoryGirl.create(normal_credit_account_type)
43
- other_account = FactoryGirl.create("not_#{normal_credit_account_type}".to_sym)
44
- t = FactoryGirl.build(:transaction)
45
- t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: 50, account: other_account)
46
- t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: 50, account: account)
47
- t.save
48
- DoubleDouble.const_get(normal_credit_account_type.to_s.capitalize).should respond_to(:balance)
49
- DoubleDouble.const_get(normal_credit_account_type.to_s.capitalize).balance.should < 0
50
- DoubleDouble.const_get(normal_credit_account_type.to_s.capitalize).balance.should be_kind_of(Money)
42
+ it "should report a NEGATIVE balance across the account type when DEBITED
43
+ and using an unrelated type for the balanced side transaction" do
44
+ DoubleDouble::Transaction.create!(
45
+ description: 'Sold some widgets',
46
+ debits: [{account: 'acct1', amount: Money.new(50)}],
47
+ credits: [{account: 'other_account', amount: Money.new(50)}])
48
+ DoubleDouble.const_get(normal_credit_account_type.to_s.capitalize).should respond_to(:balance)
49
+ DoubleDouble.const_get(normal_credit_account_type.to_s.capitalize).balance.should < 0
50
+ DoubleDouble.const_get(normal_credit_account_type.to_s.capitalize).balance.should be_kind_of(Money)
51
+ end
51
52
  end
52
53
 
53
- it "should return the balance with respect to project_id, if project_id is supplied" do
54
- acct1 = FactoryGirl.create(normal_credit_account_type, name: 'acct1')
55
- acct2 = FactoryGirl.create(normal_credit_account_type, name: 'acct2')
56
- other_account = FactoryGirl.create("not_#{normal_credit_account_type}".to_sym, name: 'other_account')
57
- a1 = rand(1_000_000_000)
58
- a2 = rand(1_000_000_000)
59
- a3 = rand(1_000_000_000)
60
- a4 = rand(1_000_000_000)
61
- @project1 = FactoryGirl.create(normal_credit_account_type)
62
- @invoice555 = FactoryGirl.create(normal_credit_account_type)
54
+ describe "context" do
55
+
56
+ it "should return the balance with respect to context is supplied" do
57
+ acct1 = FactoryGirl.create(normal_credit_account_type, name: 'acct1')
58
+ acct2 = FactoryGirl.create(normal_credit_account_type, name: 'acct2')
59
+ other_account = FactoryGirl.create("not_#{normal_credit_account_type}".to_sym, name: 'other_account')
60
+ a1 = rand(1_000_000_000)
61
+ a2 = rand(1_000_000_000)
62
+ a3 = rand(1_000_000_000)
63
+ a4 = rand(1_000_000_000)
64
+ @project1 = FactoryGirl.create(normal_credit_account_type)
65
+ @invoice555 = FactoryGirl.create(normal_credit_account_type)
63
66
 
64
- DoubleDouble::Transaction.create!(
65
- description: 'Sold some widgets',
66
- debits: [{account: 'other_account', amount: Money.new(a1)}],
67
- credits: [{account: 'acct1', amount: Money.new(a1), context: @project1}])
68
- DoubleDouble::Transaction.create!(
69
- description: 'Sold something',
70
- debits: [{account: 'other_account', amount: Money.new(a2)}],
71
- credits: [{account: 'acct1', amount: Money.new(a2), context: @project1}])
72
- DoubleDouble::Transaction.create!(
73
- description: 'Sold something',
74
- debits: [{account: 'other_account', amount: Money.new(a3)}],
75
- credits: [{account: 'acct1', amount: Money.new(a3), context: @invoice555}])
76
- DoubleDouble::Transaction.create!(
77
- description: 'Sold something',
78
- debits: [{account: 'other_account', amount: Money.new(a3)}],
79
- credits: [{account: 'acct1', amount: Money.new(a3)}])
67
+ DoubleDouble::Transaction.create!(
68
+ description: 'Sold some widgets',
69
+ debits: [{account: 'other_account', amount: Money.new(a1)}],
70
+ credits: [{account: 'acct1', amount: Money.new(a1), context: @project1}])
71
+ DoubleDouble::Transaction.create!(
72
+ description: 'Sold something',
73
+ debits: [{account: 'other_account', amount: Money.new(a2)}],
74
+ credits: [{account: 'acct1', amount: Money.new(a2), context: @project1}])
75
+ DoubleDouble::Transaction.create!(
76
+ description: 'Sold something',
77
+ debits: [{account: 'other_account', amount: Money.new(a3)}],
78
+ credits: [{account: 'acct1', amount: Money.new(a3), context: @invoice555}])
79
+ DoubleDouble::Transaction.create!(
80
+ description: 'Sold something',
81
+ debits: [{account: 'other_account', amount: Money.new(a3)}],
82
+ credits: [{account: 'acct1', amount: Money.new(a3)}])
80
83
 
81
- DoubleDouble::Transaction.create!(
82
- description: 'Sold something',
83
- debits: [{account: 'acct1', amount: Money.new(a4), context: @project1}],
84
- credits: [{account: 'other_account', amount: Money.new(a4)}])
85
- DoubleDouble::Transaction.create!(
86
- description: 'Sold something',
87
- debits: [{account: 'acct1', amount: Money.new(a2), context: @project1}],
88
- credits: [{account: 'other_account', amount: Money.new(a2)}])
89
- DoubleDouble::Transaction.create!(
90
- description: 'Sold something',
91
- debits: [{account: 'acct1', amount: Money.new(a3), context: @invoice555}],
92
- credits: [{account: 'other_account', amount: Money.new(a3)}])
93
- DoubleDouble::Transaction.create!(
94
- description: 'Sold something',
95
- debits: [{account: 'acct1', amount: Money.new(a3)}],
96
- credits: [{account: 'other_account', amount: Money.new(a3)}])
84
+ DoubleDouble::Transaction.create!(
85
+ description: 'Sold something',
86
+ debits: [{account: 'acct1', amount: Money.new(a4), context: @project1}],
87
+ credits: [{account: 'other_account', amount: Money.new(a4)}])
88
+ DoubleDouble::Transaction.create!(
89
+ description: 'Sold something',
90
+ debits: [{account: 'acct1', amount: Money.new(a2), context: @project1}],
91
+ credits: [{account: 'other_account', amount: Money.new(a2)}])
92
+ DoubleDouble::Transaction.create!(
93
+ description: 'Sold something',
94
+ debits: [{account: 'acct1', amount: Money.new(a3), context: @invoice555}],
95
+ credits: [{account: 'other_account', amount: Money.new(a3)}])
96
+ DoubleDouble::Transaction.create!(
97
+ description: 'Sold something',
98
+ debits: [{account: 'acct1', amount: Money.new(a3)}],
99
+ credits: [{account: 'other_account', amount: Money.new(a3)}])
97
100
 
98
- DoubleDouble::Transaction.create!(
99
- description: 'Sold something',
100
- debits: [{account: 'acct2', amount: Money.new(a4), context: @project1}],
101
- credits: [{account: 'other_account', amount: Money.new(a4)}])
102
- DoubleDouble::Transaction.create!(
103
- description: 'Sold something',
104
- debits: [{account: 'acct2', amount: Money.new(a2), context: @project1}],
105
- credits: [{account: 'other_account', amount: Money.new(a2)}])
106
- DoubleDouble::Transaction.create!(
107
- description: 'Sold something',
108
- debits: [{account: 'acct2', amount: Money.new(a3), context: @invoice555}],
109
- credits: [{account: 'other_account', amount: Money.new(a3)}])
110
- DoubleDouble::Transaction.create!(
111
- description: 'Sold something',
112
- debits: [{account: 'acct2', amount: Money.new(a3)}],
113
- credits: [{account: 'other_account', amount: Money.new(a3)}])
101
+ DoubleDouble::Transaction.create!(
102
+ description: 'Sold something',
103
+ debits: [{account: 'acct2', amount: Money.new(a4), context: @project1}],
104
+ credits: [{account: 'other_account', amount: Money.new(a4)}])
105
+ DoubleDouble::Transaction.create!(
106
+ description: 'Sold something',
107
+ debits: [{account: 'acct2', amount: Money.new(a2), context: @project1}],
108
+ credits: [{account: 'other_account', amount: Money.new(a2)}])
109
+ DoubleDouble::Transaction.create!(
110
+ description: 'Sold something',
111
+ debits: [{account: 'acct2', amount: Money.new(a3), context: @invoice555}],
112
+ credits: [{account: 'other_account', amount: Money.new(a3)}])
113
+ DoubleDouble::Transaction.create!(
114
+ description: 'Sold something',
115
+ debits: [{account: 'acct2', amount: Money.new(a3)}],
116
+ credits: [{account: 'other_account', amount: Money.new(a3)}])
114
117
 
115
- acct1.balance({context: @project1}).should == Money.new((a1 + a2) - (a4 + a2))
116
- acct1.balance({context: @invoice555}).should == Money.new(a3 - a3)
117
- acct1.balance.should == Money.new((a1 + a2 + a3 + a3) - (a4 + a2 + a3 + a3))
118
-
119
- acct2.balance({context: @project1}).should == Money.new(- (a4 + a2))
120
- acct2.balance({context: @invoice555}).should == Money.new(- a3)
121
- acct2.balance.should == Money.new(- (a4 + a2 + a3 + a3))
118
+ acct1.balance({context: @project1}).should == Money.new((a1 + a2) - (a4 + a2))
119
+ acct1.balance({context: @invoice555}).should == Money.new(a3 - a3)
120
+ acct1.balance.should == Money.new((a1 + a2 + a3 + a3) - (a4 + a2 + a3 + a3))
121
+
122
+ acct2.balance({context: @project1}).should == Money.new(- (a4 + a2))
123
+ acct2.balance({context: @invoice555}).should == Money.new(- a3)
124
+ acct2.balance.should == Money.new(- (a4 + a2 + a3 + a3))
125
+ end
122
126
  end
123
127
  end
124
128
  end
@@ -1,124 +1,128 @@
1
1
  # Asset and Expense account types
2
2
  shared_examples "a normal debit account type" do
3
3
  describe "<<" do
4
+
5
+ describe "basic behavior" do
6
+
7
+ before(:each) do
8
+ @acct1 = FactoryGirl.create(normal_debit_account_type, name: 'acct1')
9
+ @acct2_contra = FactoryGirl.create(normal_debit_account_type, name: 'acct2_contra', :contra => true)
10
+ @other_account = FactoryGirl.create("not_#{normal_debit_account_type}".to_sym, name: 'other_account')
11
+ end
4
12
 
5
- it "should report a POSITIVE balance when an account is DEBITED" do
6
- account = FactoryGirl.create(normal_debit_account_type)
7
- contra_account = FactoryGirl.create(normal_debit_account_type, :contra => true)
8
- t = FactoryGirl.build(:transaction)
9
- t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: 75, account: account)
10
- t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: 75, account: contra_account)
11
- t.save
12
- account.balance.should > 0
13
- contra_account.balance.should > 0
14
- end
13
+ it "should report a POSITIVE balance when an account is DEBITED" do
14
+ DoubleDouble::Transaction.create!(
15
+ description: 'Sold some widgets',
16
+ debits: [{account: 'acct1', amount: Money.new(75)}],
17
+ credits: [{account: 'acct2_contra', amount: Money.new(75)}])
18
+ @acct1.balance.should > 0
19
+ @acct2_contra.balance.should > 0
20
+ end
15
21
 
16
- it "should report a NEGATIVE balance when an account is CREDITED" do
17
- account = FactoryGirl.create(normal_debit_account_type)
18
- contra_account = FactoryGirl.create(normal_debit_account_type, :contra => true)
19
- t = FactoryGirl.build(:transaction)
20
- t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: 75, account: account)
21
- t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: 75, account: contra_account)
22
- t.save
23
- account.balance.should < 0
24
- contra_account.balance.should < 0
25
- end
22
+ it "should report a NEGATIVE balance when an account is CREDITED" do
23
+ DoubleDouble::Transaction.create!(
24
+ description: 'Sold some widgets',
25
+ debits: [{account: 'acct2_contra', amount: Money.new(75)}],
26
+ credits: [{account: 'acct1', amount: Money.new(75)}])
27
+ @acct1.balance.should < 0
28
+ @acct2_contra.balance.should < 0
29
+ end
26
30
 
27
- it "should report a NEGATIVE balance across the account type when CREDITED
28
- and using an unrelated type for the balanced side transaction" do
29
- account = FactoryGirl.create(normal_debit_account_type)
30
- other_account = FactoryGirl.create("not_#{normal_debit_account_type}".to_sym)
31
- t = FactoryGirl.build(:transaction)
32
- t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: 50, account: account)
33
- t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: 50, account: other_account)
34
- t.save
35
- DoubleDouble.const_get(normal_debit_account_type.to_s.capitalize).should respond_to(:balance)
36
- DoubleDouble.const_get(normal_debit_account_type.to_s.capitalize).balance.should < 0
37
- DoubleDouble.const_get(normal_debit_account_type.to_s.capitalize).balance.should be_kind_of(Money)
38
- end
31
+ it "should report a NEGATIVE balance across the account type when CREDITED
32
+ and using an unrelated type for the balanced side transaction" do
33
+ DoubleDouble::Transaction.create!(
34
+ description: 'Sold some widgets',
35
+ debits: [{account: 'other_account', amount: Money.new(50)}],
36
+ credits: [{account: 'acct1', amount: Money.new(50)}])
37
+ DoubleDouble.const_get(normal_debit_account_type.to_s.capitalize).should respond_to(:balance)
38
+ DoubleDouble.const_get(normal_debit_account_type.to_s.capitalize).balance.should < 0
39
+ DoubleDouble.const_get(normal_debit_account_type.to_s.capitalize).balance.should be_kind_of(Money)
40
+ end
39
41
 
40
- it "should report a POSITIVE balance across the account type when DEBITED
41
- and using an unrelated type for the balanced side transaction" do
42
- account = FactoryGirl.create(normal_debit_account_type)
43
- other_account = FactoryGirl.create("not_#{normal_debit_account_type}".to_sym)
44
- t = FactoryGirl.build(:transaction)
45
- t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: 50, account: other_account)
46
- t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: 50, account: account)
47
- t.save
48
- DoubleDouble.const_get(normal_debit_account_type.to_s.capitalize).should respond_to(:balance)
49
- DoubleDouble.const_get(normal_debit_account_type.to_s.capitalize).balance.should > 0
50
- DoubleDouble.const_get(normal_debit_account_type.to_s.capitalize).balance.should be_kind_of(Money)
42
+ it "should report a POSITIVE balance across the account type when DEBITED
43
+ and using an unrelated type for the balanced side transaction" do
44
+ DoubleDouble::Transaction.create!(
45
+ description: 'Sold some widgets',
46
+ debits: [{account: 'acct1', amount: Money.new(50)}],
47
+ credits: [{account: 'other_account', amount: Money.new(50)}])
48
+ DoubleDouble.const_get(normal_debit_account_type.to_s.capitalize).should respond_to(:balance)
49
+ DoubleDouble.const_get(normal_debit_account_type.to_s.capitalize).balance.should > 0
50
+ DoubleDouble.const_get(normal_debit_account_type.to_s.capitalize).balance.should be_kind_of(Money)
51
+ end
51
52
  end
52
53
 
53
- it "should return the balance with respect to project_id, if project_id is supplied" do
54
- acct1 = FactoryGirl.create(normal_debit_account_type, name: 'acct1')
55
- acct2 = FactoryGirl.create(normal_debit_account_type, name: 'acct2')
56
- other_account = FactoryGirl.create("not_#{normal_debit_account_type}".to_sym, name: 'other_account')
57
- a1 = rand(1_000_000_000)
58
- a2 = rand(1_000_000_000)
59
- a3 = rand(1_000_000_000)
60
- a4 = rand(1_000_000_000)
61
- @project1 = FactoryGirl.create(normal_debit_account_type)
62
- @invoice555 = FactoryGirl.create(normal_debit_account_type)
54
+ describe "context" do
55
+
56
+ it "should return the balance with respect to context is supplied" do
57
+ acct1 = FactoryGirl.create(normal_debit_account_type, name: 'acct1')
58
+ acct2 = FactoryGirl.create(normal_debit_account_type, name: 'acct2')
59
+ other_account = FactoryGirl.create("not_#{normal_debit_account_type}".to_sym, name: 'other_account')
60
+ a1 = rand(1_000_000_000)
61
+ a2 = rand(1_000_000_000)
62
+ a3 = rand(1_000_000_000)
63
+ a4 = rand(1_000_000_000)
64
+ @project1 = FactoryGirl.create(normal_debit_account_type)
65
+ @invoice555 = FactoryGirl.create(normal_debit_account_type)
63
66
 
64
- DoubleDouble::Transaction.create!(
65
- description: 'Sold some widgets',
66
- debits: [{account: 'other_account', amount: Money.new(a1)}],
67
- credits: [{account: 'acct1', amount: Money.new(a1), context: @project1}])
68
- DoubleDouble::Transaction.create!(
69
- description: 'Sold something',
70
- debits: [{account: 'other_account', amount: Money.new(a2)}],
71
- credits: [{account: 'acct1', amount: Money.new(a2), context: @project1}])
72
- DoubleDouble::Transaction.create!(
73
- description: 'Sold something',
74
- debits: [{account: 'other_account', amount: Money.new(a3)}],
75
- credits: [{account: 'acct1', amount: Money.new(a3), context: @invoice555}])
76
- DoubleDouble::Transaction.create!(
77
- description: 'Sold something',
78
- debits: [{account: 'other_account', amount: Money.new(a3)}],
79
- credits: [{account: 'acct1', amount: Money.new(a3)}])
67
+ DoubleDouble::Transaction.create!(
68
+ description: 'Sold some widgets',
69
+ debits: [{account: 'other_account', amount: Money.new(a1)}],
70
+ credits: [{account: 'acct1', amount: Money.new(a1), context: @project1}])
71
+ DoubleDouble::Transaction.create!(
72
+ description: 'Sold something',
73
+ debits: [{account: 'other_account', amount: Money.new(a2)}],
74
+ credits: [{account: 'acct1', amount: Money.new(a2), context: @project1}])
75
+ DoubleDouble::Transaction.create!(
76
+ description: 'Sold something',
77
+ debits: [{account: 'other_account', amount: Money.new(a3)}],
78
+ credits: [{account: 'acct1', amount: Money.new(a3), context: @invoice555}])
79
+ DoubleDouble::Transaction.create!(
80
+ description: 'Sold something',
81
+ debits: [{account: 'other_account', amount: Money.new(a3)}],
82
+ credits: [{account: 'acct1', amount: Money.new(a3)}])
80
83
 
81
- DoubleDouble::Transaction.create!(
82
- description: 'Sold something',
83
- debits: [{account: 'acct1', amount: Money.new(a4), context: @project1}],
84
- credits: [{account: 'other_account', amount: Money.new(a4)}])
85
- DoubleDouble::Transaction.create!(
86
- description: 'Sold something',
87
- debits: [{account: 'acct1', amount: Money.new(a2), context: @project1}],
88
- credits: [{account: 'other_account', amount: Money.new(a2)}])
89
- DoubleDouble::Transaction.create!(
90
- description: 'Sold something',
91
- debits: [{account: 'acct1', amount: Money.new(a3), context: @invoice555}],
92
- credits: [{account: 'other_account', amount: Money.new(a3)}])
93
- DoubleDouble::Transaction.create!(
94
- description: 'Sold something',
95
- debits: [{account: 'acct1', amount: Money.new(a3)}],
96
- credits: [{account: 'other_account', amount: Money.new(a3)}])
84
+ DoubleDouble::Transaction.create!(
85
+ description: 'Sold something',
86
+ debits: [{account: 'acct1', amount: Money.new(a4), context: @project1}],
87
+ credits: [{account: 'other_account', amount: Money.new(a4)}])
88
+ DoubleDouble::Transaction.create!(
89
+ description: 'Sold something',
90
+ debits: [{account: 'acct1', amount: Money.new(a2), context: @project1}],
91
+ credits: [{account: 'other_account', amount: Money.new(a2)}])
92
+ DoubleDouble::Transaction.create!(
93
+ description: 'Sold something',
94
+ debits: [{account: 'acct1', amount: Money.new(a3), context: @invoice555}],
95
+ credits: [{account: 'other_account', amount: Money.new(a3)}])
96
+ DoubleDouble::Transaction.create!(
97
+ description: 'Sold something',
98
+ debits: [{account: 'acct1', amount: Money.new(a3)}],
99
+ credits: [{account: 'other_account', amount: Money.new(a3)}])
97
100
 
98
- DoubleDouble::Transaction.create!(
99
- description: 'Sold something',
100
- debits: [{account: 'acct2', amount: Money.new(a4), context: @project1}],
101
- credits: [{account: 'other_account', amount: Money.new(a4)}])
102
- DoubleDouble::Transaction.create!(
103
- description: 'Sold something',
104
- debits: [{account: 'acct2', amount: Money.new(a2), context: @project1}],
105
- credits: [{account: 'other_account', amount: Money.new(a2)}])
106
- DoubleDouble::Transaction.create!(
107
- description: 'Sold something',
108
- debits: [{account: 'acct2', amount: Money.new(a3), context: @invoice555}],
109
- credits: [{account: 'other_account', amount: Money.new(a3)}])
110
- DoubleDouble::Transaction.create!(
111
- description: 'Sold something',
112
- debits: [{account: 'acct2', amount: Money.new(a3)}],
113
- credits: [{account: 'other_account', amount: Money.new(a3)}])
101
+ DoubleDouble::Transaction.create!(
102
+ description: 'Sold something',
103
+ debits: [{account: 'acct2', amount: Money.new(a4), context: @project1}],
104
+ credits: [{account: 'other_account', amount: Money.new(a4)}])
105
+ DoubleDouble::Transaction.create!(
106
+ description: 'Sold something',
107
+ debits: [{account: 'acct2', amount: Money.new(a2), context: @project1}],
108
+ credits: [{account: 'other_account', amount: Money.new(a2)}])
109
+ DoubleDouble::Transaction.create!(
110
+ description: 'Sold something',
111
+ debits: [{account: 'acct2', amount: Money.new(a3), context: @invoice555}],
112
+ credits: [{account: 'other_account', amount: Money.new(a3)}])
113
+ DoubleDouble::Transaction.create!(
114
+ description: 'Sold something',
115
+ debits: [{account: 'acct2', amount: Money.new(a3)}],
116
+ credits: [{account: 'other_account', amount: Money.new(a3)}])
114
117
 
115
- acct1.balance({context: @project1}).should == Money.new((a4 + a2) - (a1 + a2))
116
- acct1.balance({context: @invoice555}).should == Money.new(a3 - a3)
117
- acct1.balance.should == Money.new((a4 + a2 + a3 + a3) - (a1 + a2 + a3 + a3))
118
-
119
- acct2.balance({context: @project1}).should == Money.new((a4 + a2))
120
- acct2.balance({context: @invoice555}).should == Money.new(a3)
121
- acct2.balance.should == Money.new((a4 + a2 + a3 + a3))
118
+ acct1.balance({context: @project1}).should == Money.new((a4 + a2) - (a1 + a2))
119
+ acct1.balance({context: @invoice555}).should == Money.new(a3 - a3)
120
+ acct1.balance.should == Money.new((a4 + a2 + a3 + a3) - (a1 + a2 + a3 + a3))
121
+
122
+ acct2.balance({context: @project1}).should == Money.new((a4 + a2))
123
+ acct2.balance({context: @invoice555}).should == Money.new(a3)
124
+ acct2.balance.should == Money.new((a4 + a2 + a3 + a3))
125
+ end
122
126
  end
123
127
  end
124
128
  end
@@ -0,0 +1,50 @@
1
+ shared_examples "it can run the README scenarios" do
2
+ describe "<<" do
3
+
4
+ it 'should perform BASIC SCENARIO A correctly' do
5
+ DoubleDouble::Asset.create! name:'Cash', number: 11
6
+ DoubleDouble::Liability.create! name:'Grandpa Loan', number: 12
7
+ DoubleDouble::Expense.create! name:'Spending', number: 13
8
+ # Grandpa was kind enough to loan us $800 USD in cash for college textbooks. To enter this we will require a transaction which will affect both 'Cash' and 'Grandpa Loan'
9
+ DoubleDouble::Transaction.create!(
10
+ description:
11
+ 'We received a loan from Grandpa',
12
+ debits:[
13
+ {account: 'Cash', amount: '$800'}],
14
+ credits:[
15
+ {account: 'Grandpa Loan', amount: '$800'}])
16
+ # We buy our college textbooks. Luckily we had more than enough.
17
+ DoubleDouble::Transaction.create!(
18
+ description:
19
+ 'Purchase textbooks from bookstore',
20
+ debits:[
21
+ {account: 'Spending', amount: '$480'}],
22
+ credits:[
23
+ {account: 'Cash', amount: '$480'}])
24
+ # How much cash is left?
25
+ DoubleDouble::Account.named('Cash').balance.to_s.should eq("320.00")
26
+ # We deceided that we wanted to return $320 of the loan.
27
+ DoubleDouble::Transaction.create!(
28
+ description:
29
+ 'Payed back $320 to Grandpa',
30
+ debits:[
31
+ {account: 'Grandpa Loan', amount: '$320'}],
32
+ credits:[
33
+ {account: 'Cash', amount: '$320'}])
34
+ # How much do we still owed Grandpa?
35
+ DoubleDouble::Account.named('Grandpa Loan').balance.to_s.should eq("480.00")
36
+ # How much did we spend?
37
+ DoubleDouble::Account.named('Spending').balance.to_s.should eq("480.00")
38
+ # How much cash do we have left?
39
+ DoubleDouble::Account.named('Cash').balance.to_s.should eq("0.00")
40
+ end
41
+
42
+ it 'should perform the REALISTIC SCENARIO correctly' do
43
+ pending "TODO"
44
+ end
45
+
46
+ it 'should perform the COMPLEX SCENARIO correctly' do
47
+ pending "TODO"
48
+ end
49
+ end
50
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: double_double
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-30 00:00:00.000000000 Z
12
+ date: 2013-02-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: money
@@ -156,7 +156,6 @@ files:
156
156
  - spec/factories/account_factory.rb
157
157
  - spec/factories/amount_factory.rb
158
158
  - spec/factories/transaction_factory.rb
159
- - spec/factories/transaction_type_factory.rb
160
159
  - spec/models/account_spec.rb
161
160
  - spec/models/amount_spec.rb
162
161
  - spec/models/asset_spec.rb
@@ -167,10 +166,12 @@ files:
167
166
  - spec/models/liability_spec.rb
168
167
  - spec/models/revenue_spec.rb
169
168
  - spec/models/transaction_spec.rb
169
+ - spec/models/transaction_type_spec.rb
170
170
  - spec/spec_helper.rb
171
171
  - spec/support/all_account_types.rb
172
172
  - spec/support/normal_credit_account_types.rb
173
173
  - spec/support/normal_debit_account_types.rb
174
+ - spec/support/readme_scenarios.rb
174
175
  homepage: https://github.com/crftr/double_double
175
176
  licenses: []
176
177
  post_install_message:
@@ -182,7 +183,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
182
183
  requirements:
183
184
  - - ! '>='
184
185
  - !ruby/object:Gem::Version
185
- version: '0'
186
+ version: 1.9.2
186
187
  required_rubygems_version: !ruby/object:Gem::Requirement
187
188
  none: false
188
189
  requirements:
@@ -200,7 +201,6 @@ test_files:
200
201
  - spec/factories/account_factory.rb
201
202
  - spec/factories/amount_factory.rb
202
203
  - spec/factories/transaction_factory.rb
203
- - spec/factories/transaction_type_factory.rb
204
204
  - spec/models/account_spec.rb
205
205
  - spec/models/amount_spec.rb
206
206
  - spec/models/asset_spec.rb
@@ -211,8 +211,10 @@ test_files:
211
211
  - spec/models/liability_spec.rb
212
212
  - spec/models/revenue_spec.rb
213
213
  - spec/models/transaction_spec.rb
214
+ - spec/models/transaction_type_spec.rb
214
215
  - spec/spec_helper.rb
215
216
  - spec/support/all_account_types.rb
216
217
  - spec/support/normal_credit_account_types.rb
217
218
  - spec/support/normal_debit_account_types.rb
219
+ - spec/support/readme_scenarios.rb
218
220
  has_rdoc:
@@ -1,14 +0,0 @@
1
- FactoryGirl.define do
2
- factory :transaction_type, class: DoubleDouble::TransactionType do |type|
3
- type.description { FactoryGirl.generate(:transaction_type_description) }
4
- type.number { FactoryGirl.generate(:transaction_type_number) }
5
- end
6
-
7
- sequence :transaction_type_description do |n|
8
- "transaction type description #{n}"
9
- end
10
-
11
- sequence :transaction_type_number do |n|
12
- 9000 + n
13
- end
14
- end