borutus 0.1.0

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.
Files changed (82) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +346 -0
  4. data/Rakefile +11 -0
  5. data/app/assets/javascripts/borutus/application.js +16 -0
  6. data/app/assets/javascripts/borutus/reports.js +5 -0
  7. data/app/assets/stylesheets/bootstrap-theme.min.css +5 -0
  8. data/app/assets/stylesheets/bootstrap.min.css +5 -0
  9. data/app/assets/stylesheets/borutus/application.css +19 -0
  10. data/app/controllers/borutus/accounts_controller.rb +30 -0
  11. data/app/controllers/borutus/application_controller.rb +4 -0
  12. data/app/controllers/borutus/entries_controller.rb +34 -0
  13. data/app/controllers/borutus/reports_controller.rb +40 -0
  14. data/app/models/borutus/account.rb +180 -0
  15. data/app/models/borutus/amount.rb +24 -0
  16. data/app/models/borutus/amounts_extension.rb +42 -0
  17. data/app/models/borutus/asset.rb +56 -0
  18. data/app/models/borutus/credit_amount.rb +10 -0
  19. data/app/models/borutus/debit_amount.rb +10 -0
  20. data/app/models/borutus/entry.rb +77 -0
  21. data/app/models/borutus/equity.rb +56 -0
  22. data/app/models/borutus/expense.rb +56 -0
  23. data/app/models/borutus/liability.rb +56 -0
  24. data/app/models/borutus/no_tenancy.rb +9 -0
  25. data/app/models/borutus/revenue.rb +56 -0
  26. data/app/models/borutus/tenancy.rb +15 -0
  27. data/app/views/borutus/accounts/index.html.erb +26 -0
  28. data/app/views/borutus/entries/index.html.erb +59 -0
  29. data/app/views/borutus/reports/_account.html.erb +28 -0
  30. data/app/views/borutus/reports/balance_sheet.html.erb +21 -0
  31. data/app/views/borutus/reports/income_statement.html.erb +24 -0
  32. data/app/views/layouts/borutus/_messages.html.erb +9 -0
  33. data/app/views/layouts/borutus/_navigation.html.erb +19 -0
  34. data/app/views/layouts/borutus/_navigation_links.html.erb +5 -0
  35. data/app/views/layouts/borutus/application.html.erb +19 -0
  36. data/config/backtrace_silencers.rb +7 -0
  37. data/config/database.yml +5 -0
  38. data/config/inflections.rb +10 -0
  39. data/config/mime_types.rb +5 -0
  40. data/config/routes.rb +9 -0
  41. data/config/secret_token.rb +7 -0
  42. data/config/session_store.rb +8 -0
  43. data/db/migrate/20160422010135_create_borutus_tables.rb +33 -0
  44. data/lib/borutus.rb +20 -0
  45. data/lib/borutus/engine.rb +5 -0
  46. data/lib/borutus/version.rb +3 -0
  47. data/lib/generators/borutus/USAGE +13 -0
  48. data/lib/generators/borutus/add_date_upgrade_generator.rb +11 -0
  49. data/lib/generators/borutus/base_generator.rb +19 -0
  50. data/lib/generators/borutus/borutus_generator.rb +12 -0
  51. data/lib/generators/borutus/templates/tenant_migration.rb +6 -0
  52. data/lib/generators/borutus/tenancy_generator.rb +12 -0
  53. data/lib/generators/borutus/upgrade_borutus_generator.rb +12 -0
  54. data/spec/controllers/accounts_controller_spec.rb +19 -0
  55. data/spec/controllers/entries_controller_spec.rb +19 -0
  56. data/spec/controllers/reports_controller_spec.rb +24 -0
  57. data/spec/factories/account_factory.rb +35 -0
  58. data/spec/factories/amount_factory.rb +19 -0
  59. data/spec/factories/entry_factory.rb +11 -0
  60. data/spec/lib/borutus_spec.rb +0 -0
  61. data/spec/models/account_spec.rb +140 -0
  62. data/spec/models/amount_spec.rb +13 -0
  63. data/spec/models/asset_spec.rb +7 -0
  64. data/spec/models/credit_amount_spec.rb +7 -0
  65. data/spec/models/debit_amount_spec.rb +7 -0
  66. data/spec/models/entry_spec.rb +170 -0
  67. data/spec/models/equity_spec.rb +7 -0
  68. data/spec/models/expense_spec.rb +7 -0
  69. data/spec/models/liability_spec.rb +7 -0
  70. data/spec/models/revenue_spec.rb +7 -0
  71. data/spec/models/tenancy_spec.rb +45 -0
  72. data/spec/rcov.opts +2 -0
  73. data/spec/routing/accounts_routing_spec.rb +13 -0
  74. data/spec/routing/entries_routing_spec.rb +13 -0
  75. data/spec/spec.opts +4 -0
  76. data/spec/spec_helper.rb +26 -0
  77. data/spec/support/account_shared_examples.rb +60 -0
  78. data/spec/support/active_support_helpers.rb +13 -0
  79. data/spec/support/amount_shared_examples.rb +21 -0
  80. data/spec/support/factory_girl_helpers.rb +8 -0
  81. data/spec/support/shoulda_matchers.rb +8 -0
  82. metadata +243 -0
@@ -0,0 +1,5 @@
1
+ <%# add navigation links to this file %>
2
+ <li><%= link_to "Balance Sheet", reports_balance_sheet_path%></li>
3
+ <li><%= link_to "Income Statement", reports_income_statement_path%></li>
4
+ <li><%= link_to "General Ledger", accounts_path%></li>
5
+ <li><%= link_to "Journal", entries_path%></li>
@@ -0,0 +1,19 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
5
+ <title>Borutus</title>
6
+ <%= stylesheet_link_tag "borutus/application", media: "all" %>
7
+ <%= javascript_include_tag "borutus/application" %>
8
+ <%= csrf_meta_tags %>
9
+ </head>
10
+ <body>
11
+ <header>
12
+ <%= render 'layouts/borutus/navigation' %>
13
+ </header>
14
+ <main role="main">
15
+ <%= render 'layouts/borutus/messages' %>
16
+ <%= yield %>
17
+ </main>
18
+ </body>
19
+ </html>
@@ -0,0 +1,7 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
4
+ # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
5
+
6
+ # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
7
+ # Rails.backtrace_cleaner.remove_silencers!
@@ -0,0 +1,5 @@
1
+ # config/database.yml in Rails
2
+ test:
3
+ adapter: sqlite3
4
+ database: ":memory:"
5
+ timeout: 500
@@ -0,0 +1,10 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Add new inflection rules using the following format
4
+ # (all these examples are active by default):
5
+ # ActiveSupport::Inflector.inflections do |inflect|
6
+ # inflect.plural /^(ox)$/i, '\1en'
7
+ # inflect.singular /^(ox)en/i, '\1'
8
+ # inflect.irregular 'person', 'people'
9
+ # inflect.uncountable %w( fish sheep )
10
+ # end
@@ -0,0 +1,5 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Add new mime types for use in respond_to blocks:
4
+ # Mime::Type.register "text/richtext", :rtf
5
+ # Mime::Type.register_alias "text/html", :iphone
@@ -0,0 +1,9 @@
1
+ Borutus::Engine.routes.draw do
2
+ root :to => 'reports#balance_sheet'
3
+
4
+ get 'reports/balance_sheet' => 'reports#balance_sheet'
5
+ get 'reports/income_statement' => 'reports#income_statement'
6
+
7
+ resources :accounts, only: [:index]
8
+ resources :entries, only: [:index]
9
+ end
@@ -0,0 +1,7 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Your secret key for verifying the integrity of signed cookies.
4
+ # If you change this key, all old signed cookies will become invalid!
5
+ # Make sure the secret is at least 30 characters and all random,
6
+ # no regular words or you'll be exposed to dictionary attacks.
7
+ Borutus::Application.config.secret_token = 'f6b9c48aaf200fda4bbcf1642319084d5e5cda2bd95ac0a43220aab19f4ee240f9cdab08b77c3284b3a6396b13b1fe8be12a227af04fc5f5a8b7a52b626c4fdd'
@@ -0,0 +1,8 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ Borutus::Application.config.session_store :cookie_store, :key => '_borutus_session'
4
+
5
+ # Use the database for sessions instead of the cookie-based default,
6
+ # which shouldn't be used to store highly confidential information
7
+ # (create the session table with "rails generate session_migration")
8
+ # Testtest::Application.config.session_store :active_record_store
@@ -0,0 +1,33 @@
1
+ class CreateBorutusTables < ActiveRecord::Migration[4.2]
2
+ def change
3
+ create_table :borutus_accounts do |t|
4
+ t.string :name
5
+ t.string :type
6
+ t.boolean :contra, default: false
7
+
8
+ t.timestamps
9
+ end
10
+ add_index :borutus_accounts, [:name, :type]
11
+
12
+ create_table :borutus_entries do |t|
13
+ t.string :description
14
+ t.date :date
15
+ t.integer :commercial_document_id
16
+ t.string :commercial_document_type
17
+
18
+ t.timestamps
19
+ end
20
+ add_index :borutus_entries, :date
21
+ add_index :borutus_entries, [:commercial_document_id, :commercial_document_type], :name => "index_entries_on_commercial_doc"
22
+
23
+ create_table :borutus_amounts do |t|
24
+ t.string :type
25
+ t.references :account
26
+ t.references :entry
27
+ t.decimal :amount, :precision => 20, :scale => 10
28
+ end
29
+ add_index :borutus_amounts, :type
30
+ add_index :borutus_amounts, [:account_id, :entry_id]
31
+ add_index :borutus_amounts, [:entry_id, :account_id]
32
+ end
33
+ end
@@ -0,0 +1,20 @@
1
+ # Borutus
2
+ require "rails"
3
+
4
+ module Borutus
5
+ # ------------------------------ tenancy ------------------------------
6
+ # configuration to enable or disable tenancy
7
+ mattr_accessor :enable_tenancy
8
+ enable_tenancy = false
9
+
10
+ mattr_accessor :tenant_class
11
+ tenant_class = nil
12
+
13
+
14
+ # provide hook to configure attributes
15
+ def self.config
16
+ yield(self)
17
+ end
18
+ end
19
+
20
+ require "borutus/engine"
@@ -0,0 +1,5 @@
1
+ module Borutus
2
+ class Engine < Rails::Engine
3
+ isolate_namespace Borutus
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module Borutus
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,13 @@
1
+ Description:
2
+ Generator for Borutus Plugin
3
+
4
+ Installation:
5
+ rails g borutus:install:migrations
6
+
7
+ This will:
8
+ Create a migration in the application for the "Account",
9
+ "Entry" and "Amount" tables.
10
+
11
+ Once generated, simply run:
12
+ rake db:migrate
13
+
@@ -0,0 +1,11 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/migration'
3
+ require_relative 'base_generator'
4
+
5
+ module Borutus
6
+ class AddDateUpgradeGenerator < BaseGenerator
7
+ def create_migration_file
8
+ migration_template 'add_date_migration.rb', 'db/migrate/add_date_to_borutus_entries.rb'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,19 @@
1
+ module Borutus
2
+ class BaseGenerator < Rails::Generators::Base
3
+ include Rails::Generators::Migration
4
+
5
+ def self.source_root
6
+ @source_root ||= File.join(File.dirname(__FILE__), 'templates')
7
+ end
8
+
9
+ # Implement the required interface for Rails::Generators::Migration.
10
+ # See http://apidock.com/rails/ActiveRecord/Generators/Base/next_migration_number/class
11
+ def self.next_migration_number(dirname)
12
+ if ActiveRecord::Base.timestamped_migrations
13
+ Time.now.utc.strftime("%Y%m%d%H%M%S")
14
+ else
15
+ "%.3d" % (current_migration_number(dirname) + 1)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,12 @@
1
+ # lib/generators/borutus/borutus_generator.rb
2
+ require 'rails/generators'
3
+ require 'rails/generators/migration'
4
+ require_relative 'base_generator'
5
+
6
+ module Borutus
7
+ class BorutusGenerator < BaseGenerator
8
+ def create_migration_file
9
+ migration_template 'migration.rb', 'db/migrate/create_borutus_tables.rb'
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,6 @@
1
+ class TenantBorutusTables < ActiveRecord::Migration[4.2]
2
+ def change
3
+ # add a tenant column to borutus accounts table.
4
+ add_column :borutus_accounts, :tenant_id, :integer, index: true
5
+ end
6
+ end
@@ -0,0 +1,12 @@
1
+ # lib/generators/borutus/borutus_generator.rb
2
+ require 'rails/generators'
3
+ require 'rails/generators/migration'
4
+ require_relative 'base_generator'
5
+
6
+ module Borutus
7
+ class TenancyGenerator < BaseGenerator
8
+ def create_migration_file
9
+ migration_template 'tenant_migration.rb', 'db/migrate/tenant_borutus_tables.rb'
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # lib/generators/borutus/borutus_generator.rb
2
+ require 'rails/generators'
3
+ require 'rails/generators/migration'
4
+ require_relative 'base_generator'
5
+
6
+ module Borutus
7
+ class UpgradeBorutusGenerator < BaseGenerator
8
+ def create_migration_file
9
+ migration_template 'update_migration.rb', 'db/migrate/update_borutus_tables.rb'
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ module Borutus
4
+ describe AccountsController do
5
+ routes { Borutus::Engine.routes }
6
+
7
+ def mock_account(stubs={})
8
+ @mock_account ||= FactoryGirl.create(:asset)
9
+ end
10
+
11
+ describe "GET index" do
12
+ it "assigns all accounts as @accounts" do
13
+ allow(Account).to receive(:all).and_return([mock_account])
14
+ get :index
15
+ expect(assigns[:accounts]).to eq([mock_account])
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ module Borutus
4
+ describe EntriesController do
5
+ routes { Borutus::Engine.routes }
6
+
7
+ def mock_entry(stubs={})
8
+ @mock_entry ||= FactoryGirl.create(:entry_with_credit_and_debit)
9
+ end
10
+
11
+ describe "GET index" do
12
+ it "assigns all entries as @entries" do
13
+ allow(Entry).to receive_message_chain(:per, :order).and_return([mock_entry])
14
+ get :index
15
+ expect(assigns[:entries]).to eq([mock_entry])
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ module Borutus
4
+ describe ReportsController do
5
+ routes { Borutus::Engine.routes }
6
+
7
+ def mock_entry(stubs={})
8
+ @mock_entry ||= FactoryGirl.create(:entry_with_credit_and_debit)
9
+ end
10
+
11
+ describe "GET balance_sheet" do
12
+ it "renders when one entry exists" do
13
+ allow(Entry).to receive_message_chain(:order).and_return([mock_entry])
14
+ get :balance_sheet
15
+ expect(response).to be_success
16
+ end
17
+ it "renders when no entries exist" do
18
+ allow(Entry).to receive_message_chain(:order).and_return([])
19
+ get :balance_sheet
20
+ expect(response).to be_success
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,35 @@
1
+ FactoryGirl.define do
2
+ factory :account, :class => Borutus::Account do |account|
3
+ account.name
4
+ account.contra false
5
+ end
6
+
7
+ factory :asset, :class => Borutus::Asset do |account|
8
+ account.name
9
+ account.contra false
10
+ end
11
+
12
+ factory :equity, :class => Borutus::Equity do |account|
13
+ account.name
14
+ account.contra false
15
+ end
16
+
17
+ factory :expense, :class => Borutus::Expense do |account|
18
+ account.name
19
+ account.contra false
20
+ end
21
+
22
+ factory :liability, :class => Borutus::Liability do |account|
23
+ account.name
24
+ account.contra false
25
+ end
26
+
27
+ factory :revenue, :class => Borutus::Revenue do |account|
28
+ account.name
29
+ account.contra false
30
+ end
31
+
32
+ sequence :name do |n|
33
+ "Factory Name #{n}"
34
+ end
35
+ end
@@ -0,0 +1,19 @@
1
+ FactoryGirl.define do
2
+ factory :amount, :class => Borutus::Amount do |amount|
3
+ amount.amount BigDecimal.new('473')
4
+ amount.association :entry, :factory => :entry_with_credit_and_debit
5
+ amount.association :account, :factory => :asset
6
+ end
7
+
8
+ factory :credit_amount, :class => Borutus::CreditAmount do |credit_amount|
9
+ credit_amount.amount BigDecimal.new('473')
10
+ credit_amount.association :entry, :factory => :entry_with_credit_and_debit
11
+ credit_amount.association :account, :factory => :revenue
12
+ end
13
+
14
+ factory :debit_amount, :class => Borutus::DebitAmount do |debit_amount|
15
+ debit_amount.amount BigDecimal.new('473')
16
+ debit_amount.association :entry, :factory => :entry_with_credit_and_debit
17
+ debit_amount.association :account, :factory => :asset
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ FactoryGirl.define do
2
+ factory :entry, :class => Borutus::Entry do |entry|
3
+ entry.description 'factory description'
4
+ factory :entry_with_credit_and_debit, :class => Borutus::Entry do |entry_cd|
5
+ entry_cd.after_build do |t|
6
+ t.credit_amounts << FactoryGirl.build(:credit_amount, :entry => t)
7
+ t.debit_amounts << FactoryGirl.build(:debit_amount, :entry => t)
8
+ end
9
+ end
10
+ end
11
+ end
File without changes
@@ -0,0 +1,140 @@
1
+ require 'spec_helper'
2
+
3
+ module Borutus
4
+ describe Account do
5
+ let(:account) { FactoryGirl.build(:account) }
6
+ subject { account }
7
+
8
+ it { is_expected.not_to be_valid } # must construct a child type instead
9
+
10
+ describe ".types" do
11
+ it "lists the available types" do
12
+ expect(described_class.types).
13
+ to match_array([Asset, Equity, Expense, Liability, Revenue])
14
+ end
15
+ end
16
+
17
+ describe "when using a child type" do
18
+ let(:account) { FactoryGirl.create(:account, type: "Finance::Asset") }
19
+ it { is_expected.to be_valid }
20
+
21
+ it "should be unique per name" do
22
+ conflict = FactoryGirl.build(:account, name: account.name, type: account.type)
23
+ expect(conflict).not_to be_valid
24
+ expect(conflict.errors[:name]).to eq(["has already been taken"])
25
+ end
26
+ end
27
+
28
+ it "calling the instance method #balance should raise a NoMethodError" do
29
+ expect { subject.balance }.to raise_error NoMethodError, "undefined method 'balance'"
30
+ end
31
+
32
+ it "calling the class method ::balance should raise a NoMethodError" do
33
+ expect { subject.class.balance }.to raise_error NoMethodError, "undefined method 'balance'"
34
+ end
35
+
36
+ describe ".trial_balance" do
37
+ subject { Account.trial_balance }
38
+ it { is_expected.to be_kind_of BigDecimal }
39
+
40
+ context "when given no entries" do
41
+ it { is_expected.to eq(0) }
42
+ end
43
+
44
+ context "when given correct entries" do
45
+ before {
46
+ # credit accounts
47
+ liability = FactoryGirl.create(:liability)
48
+ equity = FactoryGirl.create(:equity)
49
+ revenue = FactoryGirl.create(:revenue)
50
+ contra_asset = FactoryGirl.create(:asset, :contra => true)
51
+ contra_expense = FactoryGirl.create(:expense, :contra => true)
52
+ # credit amounts
53
+ ca1 = FactoryGirl.build(:credit_amount, :account => liability, :amount => 100000)
54
+ ca2 = FactoryGirl.build(:credit_amount, :account => equity, :amount => 1000)
55
+ ca3 = FactoryGirl.build(:credit_amount, :account => revenue, :amount => 40404)
56
+ ca4 = FactoryGirl.build(:credit_amount, :account => contra_asset, :amount => 2)
57
+ ca5 = FactoryGirl.build(:credit_amount, :account => contra_expense, :amount => 333)
58
+
59
+ # debit accounts
60
+ asset = FactoryGirl.create(:asset)
61
+ expense = FactoryGirl.create(:expense)
62
+ contra_liability = FactoryGirl.create(:liability, :contra => true)
63
+ contra_equity = FactoryGirl.create(:equity, :contra => true)
64
+ contra_revenue = FactoryGirl.create(:revenue, :contra => true)
65
+ # debit amounts
66
+ da1 = FactoryGirl.build(:debit_amount, :account => asset, :amount => 100000)
67
+ da2 = FactoryGirl.build(:debit_amount, :account => expense, :amount => 1000)
68
+ da3 = FactoryGirl.build(:debit_amount, :account => contra_liability, :amount => 40404)
69
+ da4 = FactoryGirl.build(:debit_amount, :account => contra_equity, :amount => 2)
70
+ da5 = FactoryGirl.build(:debit_amount, :account => contra_revenue, :amount => 333)
71
+
72
+ FactoryGirl.create(:entry, :credit_amounts => [ca1], :debit_amounts => [da1])
73
+ FactoryGirl.create(:entry, :credit_amounts => [ca2], :debit_amounts => [da2])
74
+ FactoryGirl.create(:entry, :credit_amounts => [ca3], :debit_amounts => [da3])
75
+ FactoryGirl.create(:entry, :credit_amounts => [ca4], :debit_amounts => [da4])
76
+ FactoryGirl.create(:entry, :credit_amounts => [ca5], :debit_amounts => [da5])
77
+ }
78
+
79
+ it { is_expected.to eq(0) }
80
+ end
81
+ end
82
+
83
+ describe "#amounts" do
84
+ it "returns all credit and debit amounts" do
85
+ equity = FactoryGirl.create(:equity)
86
+ asset = FactoryGirl.create(:asset)
87
+ expense = FactoryGirl.create(:expense)
88
+
89
+ investment = Entry.new(
90
+ description: "Initial investment",
91
+ date: Date.today,
92
+ debits: [{ account_name: equity.name, amount: 1000 }],
93
+ credits: [{ account_name: asset.name, amount: 1000 }],
94
+ )
95
+ investment.save
96
+
97
+ purchase = Entry.new(
98
+ description: "First computer",
99
+ date: Date.today,
100
+ debits: [{ account_name: asset.name, amount: 900 }],
101
+ credits: [{ account_name: expense.name, amount: 900 }],
102
+ )
103
+ purchase.save
104
+
105
+ expect(equity.amounts.size).to eq 1
106
+ expect(asset.amounts.size).to eq 2
107
+ expect(expense.amounts.size).to eq 1
108
+ end
109
+ end
110
+
111
+ describe "#entries" do
112
+ it "returns all credit and debit entries" do
113
+ equity = FactoryGirl.create(:equity)
114
+ asset = FactoryGirl.create(:asset)
115
+ expense = FactoryGirl.create(:expense)
116
+
117
+ investment = Entry.new(
118
+ description: "Initial investment",
119
+ date: Date.today,
120
+ debits: [{ account_name: equity.name, amount: 1000 }],
121
+ credits: [{ account_name: asset.name, amount: 1000 }],
122
+ )
123
+ investment.save
124
+
125
+ purchase = Entry.new(
126
+ description: "First computer",
127
+ date: Date.today,
128
+ debits: [{ account_name: asset.name, amount: 900 }],
129
+ credits: [{ account_name: expense.name, amount: 900 }],
130
+ )
131
+ purchase.save
132
+
133
+ expect(equity.entries.size).to eq 1
134
+ expect(asset.entries.size).to eq 2
135
+ expect(expense.entries.size).to eq 1
136
+ end
137
+ end
138
+
139
+ end
140
+ end