double_double 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/.gitignore +18 -0
  2. data/.rspec +3 -0
  3. data/.travis.yml +10 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +38 -0
  7. data/Rakefile +10 -0
  8. data/double_double.gemspec +27 -0
  9. data/lib/double_double/account.rb +85 -0
  10. data/lib/double_double/amount.rb +33 -0
  11. data/lib/double_double/asset.rb +25 -0
  12. data/lib/double_double/credit_amount.rb +9 -0
  13. data/lib/double_double/debit_amount.rb +9 -0
  14. data/lib/double_double/equity.rb +26 -0
  15. data/lib/double_double/expense.rb +26 -0
  16. data/lib/double_double/liability.rb +25 -0
  17. data/lib/double_double/revenue.rb +26 -0
  18. data/lib/double_double/transaction.rb +88 -0
  19. data/lib/double_double/transaction_type.rb +13 -0
  20. data/lib/double_double/version.rb +3 -0
  21. data/lib/double_double.rb +21 -0
  22. data/spec/factories/account_factory.rb +27 -0
  23. data/spec/factories/amount_factory.rb +10 -0
  24. data/spec/factories/transaction_factory.rb +9 -0
  25. data/spec/factories/transaction_type_factory.rb +14 -0
  26. data/spec/models/account_spec.rb +70 -0
  27. data/spec/models/amount_spec.rb +9 -0
  28. data/spec/models/asset_spec.rb +12 -0
  29. data/spec/models/credit_amount_spec.rb +46 -0
  30. data/spec/models/debit_amount_spec.rb +46 -0
  31. data/spec/models/equity_spec.rb +12 -0
  32. data/spec/models/expense_spec.rb +12 -0
  33. data/spec/models/liability_spec.rb +12 -0
  34. data/spec/models/revenue_spec.rb +12 -0
  35. data/spec/models/transaction_spec.rb +101 -0
  36. data/spec/spec_helper.rb +87 -0
  37. data/spec/support/all_account_types.rb +50 -0
  38. data/spec/support/left_side_account_types.rb +125 -0
  39. data/spec/support/right_side_account_types.rb +125 -0
  40. metadata +216 -0
@@ -0,0 +1,87 @@
1
+ require 'database_cleaner'
2
+ require 'double_double'
3
+ require 'factory_girl'
4
+
5
+ require 'pry'
6
+
7
+ # Create an in-memory database and run our minimal migration
8
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
9
+ ActiveRecord::Migration.verbose = false
10
+ @migration = Class.new(ActiveRecord::Migration) do
11
+ def change
12
+ create_table :double_double_accounts do |t|
13
+ t.integer :number, null: false
14
+ t.string :name
15
+ t.string :type
16
+ t.boolean :contra
17
+
18
+ t.timestamps
19
+ end
20
+ add_index :double_double_accounts, [:name, :type]
21
+
22
+ create_table :double_double_transactions do |t|
23
+ t.string :description
24
+ t.integer :commercial_document_id
25
+ t.string :commercial_document_type
26
+ t.references :transaction_type
27
+ t.timestamps
28
+ end
29
+ add_index :double_double_transactions, [:commercial_document_id, :commercial_document_type], :name => "index_transactions_on_commercial_doc"
30
+ add_index :double_double_transactions, :transaction_type_id
31
+
32
+ create_table :double_double_transaction_types do |t|
33
+ t.integer :number, null: false
34
+ t.string :description, null: false
35
+ end
36
+ add_index :double_double_transaction_types, :number
37
+
38
+ create_table :double_double_amounts do |t|
39
+ t.string :type
40
+ t.references :account
41
+ t.references :transaction
42
+ t.references :project
43
+ t.references :approving_user
44
+ t.references :targeted_user
45
+ t.integer :amount_cents, :limit => 8, :default => 0, :null => false
46
+ t.string :currency
47
+ end
48
+ add_index :double_double_amounts, :project_id
49
+ add_index :double_double_amounts, :approving_user_id
50
+ add_index :double_double_amounts, :targeted_user_id
51
+ add_index :double_double_amounts, :type
52
+ add_index :double_double_amounts, [:account_id, :transaction_id]
53
+ add_index :double_double_amounts, [:transaction_id, :account_id]
54
+ end
55
+ end
56
+ @migration.new.migrate(:up)
57
+
58
+ # Load factories
59
+ Dir[File.expand_path(File.join(File.dirname(__FILE__),'factories','**','*.rb'))].each {|f| require f}
60
+
61
+ # Load left and right side rspec shared examples
62
+ Dir["./spec/support/**/*.rb"].sort.each {|f| require f}
63
+
64
+ RSpec.configure do |config|
65
+ config.treat_symbols_as_metadata_keys_with_true_values = true
66
+ config.run_all_when_everything_filtered = true
67
+ config.filter_run :focus
68
+
69
+ # Run specs in random order to surface order dependencies. If you find an
70
+ # order dependency and want to debug it, you can fix the order by providing
71
+ # the seed, which is printed after each run.
72
+ # --seed 1234
73
+ config.order = 'random'
74
+
75
+ config.before(:suite) do
76
+ DatabaseCleaner.strategy = :transaction
77
+ DatabaseCleaner.clean_with(:truncation)
78
+ end
79
+
80
+ config.before(:each) do
81
+ DatabaseCleaner.start
82
+ end
83
+
84
+ config.after(:each) do
85
+ DatabaseCleaner.clean
86
+ end
87
+ end
@@ -0,0 +1,50 @@
1
+ # The shared behaviors that all account types should exhibit.
2
+ #
3
+ # For clarification, the following will return the class object represented in account_type
4
+ #
5
+ # @example
6
+ # account_type = :asset
7
+ # DoubleDouble.const_get(account_type.to_s.capitalize) # returns the DoubleDouble::Asset class object
8
+
9
+ shared_examples "all account types" do
10
+ describe "<<" do
11
+
12
+ before(:all) do
13
+ @capitalized_account_type = account_type.to_s.capitalize
14
+ end
15
+
16
+ it "should allow creating an account" do
17
+ -> { account = FactoryGirl.create(account_type) }.should change(DoubleDouble::Account, :count).by(1)
18
+ end
19
+
20
+ it "should not report a trial balance" do
21
+ -> { DoubleDouble.const_get(@capitalized_account_type).trial_balance }.should raise_error(NoMethodError)
22
+ end
23
+
24
+ it "should not be valid without a name" do
25
+ account = FactoryGirl.build(account_type, :name => nil)
26
+ account.should_not be_valid
27
+ end
28
+
29
+ it "should respond_to credit_transactions" do
30
+ account = FactoryGirl.build(account_type)
31
+ account.should respond_to(:credit_transactions)
32
+ end
33
+
34
+ it "should respond_to debit_transactions" do
35
+ account = FactoryGirl.build(account_type)
36
+ account.should respond_to(:debit_transactions)
37
+ end
38
+
39
+ it "a contra account should be capable of balancing against a non-contra account" do
40
+ account = FactoryGirl.create(account_type)
41
+ contra_account = FactoryGirl.create(account_type, :contra => true)
42
+ t = FactoryGirl.build(:transaction)
43
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: 50, account: account)
44
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: 25, account: account)
45
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: 75, account: contra_account)
46
+ t.save
47
+ DoubleDouble.const_get(@capitalized_account_type).balance.should == 0
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,125 @@
1
+ # Asset and Expense account types
2
+
3
+ shared_examples "a left side account type" do
4
+ describe "<<" do
5
+
6
+ it "should report a POSITIVE balance when an account is DEBITED" do
7
+ account = FactoryGirl.create(left_side_account_type)
8
+ contra_account = FactoryGirl.create(left_side_account_type, :contra => true)
9
+ t = FactoryGirl.build(:transaction)
10
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: 75, account: account)
11
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: 75, account: contra_account)
12
+ t.save
13
+ account.balance.should > 0
14
+ contra_account.balance.should > 0
15
+ end
16
+
17
+ it "should report a NEGATIVE balance when an account is CREDITED" do
18
+ account = FactoryGirl.create(left_side_account_type)
19
+ contra_account = FactoryGirl.create(left_side_account_type, :contra => true)
20
+ t = FactoryGirl.build(:transaction)
21
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: 75, account: account)
22
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: 75, account: contra_account)
23
+ t.save
24
+ account.balance.should < 0
25
+ contra_account.balance.should < 0
26
+ end
27
+
28
+ it "should report a NEGATIVE balance across the account type when CREDITED
29
+ and using an unrelated type for the balanced side transaction" do
30
+ account = FactoryGirl.create(left_side_account_type)
31
+ other_account = FactoryGirl.create("not_#{left_side_account_type}".to_sym)
32
+ t = FactoryGirl.build(:transaction)
33
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: 50, account: account)
34
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: 50, account: other_account)
35
+ t.save
36
+ DoubleDouble.const_get(left_side_account_type.to_s.capitalize).should respond_to(:balance)
37
+ DoubleDouble.const_get(left_side_account_type.to_s.capitalize).balance.should < 0
38
+ DoubleDouble.const_get(left_side_account_type.to_s.capitalize).balance.should be_kind_of(Money)
39
+ end
40
+
41
+ it "should report a POSITIVE balance across the account type when DEBITED
42
+ and using an unrelated type for the balanced side transaction" do
43
+ account = FactoryGirl.create(left_side_account_type)
44
+ other_account = FactoryGirl.create("not_#{left_side_account_type}".to_sym)
45
+ t = FactoryGirl.build(:transaction)
46
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: 50, account: other_account)
47
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: 50, account: account)
48
+ t.save
49
+ DoubleDouble.const_get(left_side_account_type.to_s.capitalize).should respond_to(:balance)
50
+ DoubleDouble.const_get(left_side_account_type.to_s.capitalize).balance.should > 0
51
+ DoubleDouble.const_get(left_side_account_type.to_s.capitalize).balance.should be_kind_of(Money)
52
+ end
53
+
54
+ it "should return the balance with respect to project_id, if project_id is supplied" do
55
+ acct1 = FactoryGirl.create(left_side_account_type)
56
+ acct2 = FactoryGirl.create(left_side_account_type)
57
+ other_account = FactoryGirl.create("not_#{left_side_account_type}".to_sym)
58
+ a1 = rand(1_000_000_000)
59
+ a2 = rand(1_000_000_000)
60
+ a3 = rand(1_000_000_000)
61
+ a4 = rand(1_000_000_000)
62
+ pid1 = 100
63
+ pid2 = 200
64
+
65
+ t = FactoryGirl.build(:transaction)
66
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: Money.new(a1), account: acct1, project_id: pid1)
67
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: Money.new(a1), account: other_account)
68
+ t.save
69
+ t = FactoryGirl.build(:transaction)
70
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: Money.new(a2), account: acct1, project_id: pid1)
71
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: Money.new(a2), account: other_account)
72
+ t.save
73
+ t = FactoryGirl.build(:transaction)
74
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: Money.new(a3), account: acct1, project_id: pid2)
75
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: Money.new(a3), account: other_account)
76
+ t.save
77
+ t = FactoryGirl.build(:transaction)
78
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: Money.new(a3), account: acct1)
79
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: Money.new(a3), account: other_account)
80
+ t.save
81
+
82
+ t = FactoryGirl.build(:transaction)
83
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: Money.new(a4), account: other_account)
84
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: Money.new(a4), account: acct1, project_id: pid1)
85
+ t.save
86
+ t = FactoryGirl.build(:transaction)
87
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: Money.new(a2), account: other_account)
88
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: Money.new(a2), account: acct1, project_id: pid1)
89
+ t.save
90
+ t = FactoryGirl.build(:transaction)
91
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: Money.new(a3), account: other_account)
92
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: Money.new(a3), account: acct1, project_id: pid2)
93
+ t.save
94
+ t = FactoryGirl.build(:transaction)
95
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: Money.new(a3), account: other_account)
96
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: Money.new(a3), account: acct1)
97
+ t.save
98
+
99
+ t = FactoryGirl.build(:transaction)
100
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: Money.new(a4), account: other_account)
101
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: Money.new(a4), account: acct2, project_id: pid1)
102
+ t.save
103
+ t = FactoryGirl.build(:transaction)
104
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: Money.new(a2), account: other_account)
105
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: Money.new(a2), account: acct2, project_id: pid1)
106
+ t.save
107
+ t = FactoryGirl.build(:transaction)
108
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: Money.new(a3), account: other_account)
109
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: Money.new(a3), account: acct2, project_id: pid2)
110
+ t.save
111
+ t = FactoryGirl.build(:transaction)
112
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: Money.new(a3), account: other_account)
113
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: Money.new(a3), account: acct2)
114
+ t.save
115
+
116
+ acct1.balance({project_id: pid1}).should == Money.new((a4 + a2) - (a1 + a2))
117
+ acct1.balance({project_id: pid2}).should == Money.new(a3 - a3)
118
+ acct1.balance.should == Money.new((a4 + a2 + a3 + a3) - (a1 + a2 + a3 + a3))
119
+
120
+ acct2.balance({project_id: pid1}).should == Money.new((a4 + a2))
121
+ acct2.balance({project_id: pid2}).should == Money.new(a3)
122
+ acct2.balance.should == Money.new((a4 + a2 + a3 + a3))
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,125 @@
1
+ # Liability, Equity, and Revenue account types
2
+
3
+ shared_examples "a right side account type" do
4
+ describe "<<" do
5
+
6
+ it "should report a NEGATIVE balance when an account is debited" do
7
+ account = FactoryGirl.create(right_side_account_type)
8
+ contra_account = FactoryGirl.create(right_side_account_type, :contra => true)
9
+ t = FactoryGirl.build(:transaction)
10
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: 75, account: account)
11
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: 75, account: contra_account)
12
+ t.save
13
+ account.balance.should < 0
14
+ contra_account.balance.should < 0
15
+ end
16
+
17
+ it "should report a POSITIVE balance when an account is credited" do
18
+ account = FactoryGirl.create(right_side_account_type)
19
+ contra_account = FactoryGirl.create(right_side_account_type, :contra => true)
20
+ t = FactoryGirl.build(:transaction)
21
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: 75, account: account)
22
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: 75, account: contra_account)
23
+ t.save
24
+ account.balance.should > 0
25
+ contra_account.balance.should > 0
26
+ end
27
+
28
+ it "should report a POSITIVE balance across the account type when CREDITED
29
+ and using an unrelated type for the balanced side transaction" do
30
+ account = FactoryGirl.create(right_side_account_type)
31
+ other_account = FactoryGirl.create("not_#{right_side_account_type}".to_sym)
32
+ t = FactoryGirl.build(:transaction)
33
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: 50, account: account)
34
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: 50, account: other_account)
35
+ t.save
36
+ DoubleDouble.const_get(right_side_account_type.to_s.capitalize).should respond_to(:balance)
37
+ DoubleDouble.const_get(right_side_account_type.to_s.capitalize).balance.should > 0
38
+ DoubleDouble.const_get(right_side_account_type.to_s.capitalize).balance.should be_kind_of(Money)
39
+ end
40
+
41
+ it "should report a NEGATIVE balance across the account type when DEBITED
42
+ and using an unrelated type for the balanced side transaction" do
43
+ account = FactoryGirl.create(right_side_account_type)
44
+ other_account = FactoryGirl.create("not_#{right_side_account_type}".to_sym)
45
+ t = FactoryGirl.build(:transaction)
46
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: 50, account: other_account)
47
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: 50, account: account)
48
+ t.save
49
+ DoubleDouble.const_get(right_side_account_type.to_s.capitalize).should respond_to(:balance)
50
+ DoubleDouble.const_get(right_side_account_type.to_s.capitalize).balance.should < 0
51
+ DoubleDouble.const_get(right_side_account_type.to_s.capitalize).balance.should be_kind_of(Money)
52
+ end
53
+
54
+ it "should return the balance with respect to project_id, if project_id is supplied" do
55
+ acct1 = FactoryGirl.create(right_side_account_type)
56
+ acct2 = FactoryGirl.create(right_side_account_type)
57
+ other_account = FactoryGirl.create("not_#{right_side_account_type}".to_sym)
58
+ a1 = rand(10..1_000_000_000)
59
+ a2 = rand(10..1_000_000_000)
60
+ a3 = rand(10..1_000_000_000)
61
+ a4 = rand(10..1_000_000_000)
62
+ pid1 = 100
63
+ pid2 = 200
64
+
65
+ t = FactoryGirl.build(:transaction)
66
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: Money.new(a1), account: acct1, project_id: pid1)
67
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: Money.new(a1), account: other_account)
68
+ t.save
69
+ t = FactoryGirl.build(:transaction)
70
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: Money.new(a2), account: acct1, project_id: pid1)
71
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: Money.new(a2), account: other_account)
72
+ t.save
73
+ t = FactoryGirl.build(:transaction)
74
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: Money.new(a3), account: acct1, project_id: pid2)
75
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: Money.new(a3), account: other_account)
76
+ t.save
77
+ t = FactoryGirl.build(:transaction)
78
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: Money.new(a3), account: acct1)
79
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: Money.new(a3), account: other_account)
80
+ t.save
81
+
82
+ t = FactoryGirl.build(:transaction)
83
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: Money.new(a4), account: other_account)
84
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: Money.new(a4), account: acct1, project_id: pid1)
85
+ t.save
86
+ t = FactoryGirl.build(:transaction)
87
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: Money.new(a2), account: other_account)
88
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: Money.new(a2), account: acct1, project_id: pid1)
89
+ t.save
90
+ t = FactoryGirl.build(:transaction)
91
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: Money.new(a3), account: other_account)
92
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: Money.new(a3), account: acct1, project_id: pid2)
93
+ t.save
94
+ t = FactoryGirl.build(:transaction)
95
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: Money.new(a3), account: other_account)
96
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: Money.new(a3), account: acct1)
97
+ t.save
98
+
99
+ t = FactoryGirl.build(:transaction)
100
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: Money.new(a4), account: other_account)
101
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: Money.new(a4), account: acct2, project_id: pid1)
102
+ t.save
103
+ t = FactoryGirl.build(:transaction)
104
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: Money.new(a2), account: other_account)
105
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: Money.new(a2), account: acct2, project_id: pid1)
106
+ t.save
107
+ t = FactoryGirl.build(:transaction)
108
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: Money.new(a3), account: other_account)
109
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: Money.new(a3), account: acct2, project_id: pid2)
110
+ t.save
111
+ t = FactoryGirl.build(:transaction)
112
+ t.credit_amounts << FactoryGirl.create(:credit_amt, transaction: t, amount: Money.new(a3), account: other_account)
113
+ t.debit_amounts << FactoryGirl.create(:debit_amt, transaction: t, amount: Money.new(a3), account: acct2)
114
+ t.save
115
+
116
+ acct1.balance({project_id: pid1}).should == Money.new((a1 + a2) - (a4 + a2))
117
+ acct1.balance({project_id: pid2}).should == Money.new(a3 - a3)
118
+ acct1.balance.should == Money.new((a1 + a2 + a3 + a3) - (a4 + a2 + a3 + a3))
119
+
120
+ acct2.balance({project_id: pid1}).should == Money.new(- (a4 + a2))
121
+ acct2.balance({project_id: pid2}).should == Money.new(- a3)
122
+ acct2.balance.should == Money.new(- (a4 + a2 + a3 + a3))
123
+ end
124
+ end
125
+ end
metadata ADDED
@@ -0,0 +1,216 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: double_double
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Mike Herrera
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-26 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: money
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '5.1'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '5.1'
30
+ - !ruby/object:Gem::Dependency
31
+ name: activerecord
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 3.2.11
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 3.2.11
46
+ - !ruby/object:Gem::Dependency
47
+ name: sqlite3
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '2.12'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '2.12'
78
+ - !ruby/object:Gem::Dependency
79
+ name: factory_girl
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: database_cleaner
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: pry
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ description: A double-entry accural accounting system
127
+ email:
128
+ - git@devoplabs.com
129
+ executables: []
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - .gitignore
134
+ - .rspec
135
+ - .travis.yml
136
+ - Gemfile
137
+ - LICENSE.txt
138
+ - README.md
139
+ - Rakefile
140
+ - double_double.gemspec
141
+ - lib/double_double.rb
142
+ - lib/double_double/account.rb
143
+ - lib/double_double/amount.rb
144
+ - lib/double_double/asset.rb
145
+ - lib/double_double/credit_amount.rb
146
+ - lib/double_double/debit_amount.rb
147
+ - lib/double_double/equity.rb
148
+ - lib/double_double/expense.rb
149
+ - lib/double_double/liability.rb
150
+ - lib/double_double/revenue.rb
151
+ - lib/double_double/transaction.rb
152
+ - lib/double_double/transaction_type.rb
153
+ - lib/double_double/version.rb
154
+ - spec/factories/account_factory.rb
155
+ - spec/factories/amount_factory.rb
156
+ - spec/factories/transaction_factory.rb
157
+ - spec/factories/transaction_type_factory.rb
158
+ - spec/models/account_spec.rb
159
+ - spec/models/amount_spec.rb
160
+ - spec/models/asset_spec.rb
161
+ - spec/models/credit_amount_spec.rb
162
+ - spec/models/debit_amount_spec.rb
163
+ - spec/models/equity_spec.rb
164
+ - spec/models/expense_spec.rb
165
+ - spec/models/liability_spec.rb
166
+ - spec/models/revenue_spec.rb
167
+ - spec/models/transaction_spec.rb
168
+ - spec/spec_helper.rb
169
+ - spec/support/all_account_types.rb
170
+ - spec/support/left_side_account_types.rb
171
+ - spec/support/right_side_account_types.rb
172
+ homepage: https://github.com/crftr/double_double
173
+ licenses: []
174
+ post_install_message:
175
+ rdoc_options: []
176
+ require_paths:
177
+ - lib
178
+ required_ruby_version: !ruby/object:Gem::Requirement
179
+ none: false
180
+ requirements:
181
+ - - ! '>='
182
+ - !ruby/object:Gem::Version
183
+ version: '0'
184
+ required_rubygems_version: !ruby/object:Gem::Requirement
185
+ none: false
186
+ requirements:
187
+ - - ! '>='
188
+ - !ruby/object:Gem::Version
189
+ version: '0'
190
+ requirements: []
191
+ rubyforge_project:
192
+ rubygems_version: 1.8.23
193
+ signing_key:
194
+ specification_version: 3
195
+ summary: A double-entry accural accounting system. All currency amounts are stored
196
+ using the Money gem.
197
+ test_files:
198
+ - spec/factories/account_factory.rb
199
+ - spec/factories/amount_factory.rb
200
+ - spec/factories/transaction_factory.rb
201
+ - spec/factories/transaction_type_factory.rb
202
+ - spec/models/account_spec.rb
203
+ - spec/models/amount_spec.rb
204
+ - spec/models/asset_spec.rb
205
+ - spec/models/credit_amount_spec.rb
206
+ - spec/models/debit_amount_spec.rb
207
+ - spec/models/equity_spec.rb
208
+ - spec/models/expense_spec.rb
209
+ - spec/models/liability_spec.rb
210
+ - spec/models/revenue_spec.rb
211
+ - spec/models/transaction_spec.rb
212
+ - spec/spec_helper.rb
213
+ - spec/support/all_account_types.rb
214
+ - spec/support/left_side_account_types.rb
215
+ - spec/support/right_side_account_types.rb
216
+ has_rdoc: