double_double 0.2.0 → 0.2.3

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/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