tyche 0.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +23 -0
  3. data/README.markdown +392 -0
  4. data/Rakefile +11 -0
  5. data/app/assets/javascripts/plutus/application.js +16 -0
  6. data/app/assets/javascripts/plutus/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/plutus/application.css +19 -0
  10. data/app/controllers/plutus/accounts_controller.rb +30 -0
  11. data/app/controllers/plutus/application_controller.rb +4 -0
  12. data/app/controllers/plutus/entries_controller.rb +34 -0
  13. data/app/controllers/plutus/reports_controller.rb +40 -0
  14. data/app/models/plutus/account.rb +172 -0
  15. data/app/models/plutus/amount.rb +24 -0
  16. data/app/models/plutus/amounts_extension.rb +42 -0
  17. data/app/models/plutus/asset.rb +56 -0
  18. data/app/models/plutus/balance_finders/base_balance_finder.rb +13 -0
  19. data/app/models/plutus/credit_amount.rb +10 -0
  20. data/app/models/plutus/debit_amount.rb +10 -0
  21. data/app/models/plutus/entry.rb +77 -0
  22. data/app/models/plutus/equity.rb +56 -0
  23. data/app/models/plutus/expense.rb +56 -0
  24. data/app/models/plutus/liability.rb +56 -0
  25. data/app/models/plutus/no_tenancy.rb +9 -0
  26. data/app/models/plutus/revenue.rb +56 -0
  27. data/app/models/plutus/tenancy.rb +15 -0
  28. data/app/views/layouts/plutus/_messages.html.erb +9 -0
  29. data/app/views/layouts/plutus/_navigation.html.erb +19 -0
  30. data/app/views/layouts/plutus/_navigation_links.html.erb +5 -0
  31. data/app/views/layouts/plutus/application.html.erb +19 -0
  32. data/app/views/plutus/accounts/index.html.erb +26 -0
  33. data/app/views/plutus/entries/index.html.erb +59 -0
  34. data/app/views/plutus/reports/_account.html.erb +28 -0
  35. data/app/views/plutus/reports/balance_sheet.html.erb +21 -0
  36. data/app/views/plutus/reports/income_statement.html.erb +24 -0
  37. data/config/backtrace_silencers.rb +7 -0
  38. data/config/database.yml +5 -0
  39. data/config/inflections.rb +10 -0
  40. data/config/mime_types.rb +5 -0
  41. data/config/routes.rb +9 -0
  42. data/config/secret_token.rb +7 -0
  43. data/config/session_store.rb +8 -0
  44. data/db/migrate/20160422010135_create_plutus_tables.rb +35 -0
  45. data/lib/generators/plutus/USAGE +22 -0
  46. data/lib/generators/plutus/add_date_upgrade_generator.rb +11 -0
  47. data/lib/generators/plutus/base_generator.rb +19 -0
  48. data/lib/generators/plutus/plutus_generator.rb +12 -0
  49. data/lib/generators/plutus/templates/tenant_migration.rb +6 -0
  50. data/lib/generators/plutus/tenancy_generator.rb +12 -0
  51. data/lib/generators/plutus/upgrade_plutus_generator.rb +12 -0
  52. data/lib/plutus.rb +20 -0
  53. data/lib/plutus/engine.rb +5 -0
  54. data/lib/plutus/version.rb +3 -0
  55. data/spec/controllers/accounts_controller_spec.rb +19 -0
  56. data/spec/controllers/entries_controller_spec.rb +19 -0
  57. data/spec/controllers/reports_controller_spec.rb +24 -0
  58. data/spec/factories/account_factory.rb +35 -0
  59. data/spec/factories/amount_factory.rb +20 -0
  60. data/spec/factories/entry_factory.rb +11 -0
  61. data/spec/lib/plutus_spec.rb +0 -0
  62. data/spec/models/account_spec.rb +133 -0
  63. data/spec/models/amount_spec.rb +13 -0
  64. data/spec/models/asset_spec.rb +7 -0
  65. data/spec/models/credit_amount_spec.rb +7 -0
  66. data/spec/models/debit_amount_spec.rb +7 -0
  67. data/spec/models/entry_spec.rb +182 -0
  68. data/spec/models/equity_spec.rb +7 -0
  69. data/spec/models/expense_spec.rb +7 -0
  70. data/spec/models/liability_spec.rb +7 -0
  71. data/spec/models/revenue_spec.rb +7 -0
  72. data/spec/models/tenancy_spec.rb +45 -0
  73. data/spec/rcov.opts +2 -0
  74. data/spec/routing/accounts_routing_spec.rb +13 -0
  75. data/spec/routing/entries_routing_spec.rb +13 -0
  76. data/spec/spec.opts +4 -0
  77. data/spec/spec_helper.rb +30 -0
  78. data/spec/support/account_shared_examples.rb +62 -0
  79. data/spec/support/active_support_helpers.rb +13 -0
  80. data/spec/support/amount_shared_examples.rb +21 -0
  81. data/spec/support/factory_girl_helpers.rb +8 -0
  82. data/spec/support/shoulda_matchers.rb +8 -0
  83. metadata +240 -0
@@ -0,0 +1,13 @@
1
+ module Plutus
2
+ module BalanceFinders
3
+ class BaseBalanceFinder
4
+ attr_reader :amounts
5
+ def initialize(args)
6
+ @amounts = args.fetch(:amounts)
7
+ end
8
+ def compute
9
+ amounts.total
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ module Plutus
2
+ # The CreditAmount class represents credit entries in the entry journal.
3
+ #
4
+ # @example
5
+ # credit_amount = Plutus::CreditAmount.new(:account => revenue, :amount => 1000)
6
+ #
7
+ # @author Michael Bulat
8
+ class CreditAmount < Amount
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module Plutus
2
+ # The DebitAmount class represents debit entries in the entry journal.
3
+ #
4
+ # @example
5
+ # debit_amount = Plutus::DebitAmount.new(:account => cash, :amount => 1000)
6
+ #
7
+ # @author Michael Bulat
8
+ class DebitAmount < Amount
9
+ end
10
+ end
@@ -0,0 +1,77 @@
1
+ module Plutus
2
+ # Entries are the recording of debits and credits to various accounts.
3
+ # This table can be thought of as a traditional accounting Journal.
4
+ #
5
+ # Posting to a Ledger can be considered to happen automatically, since
6
+ # Accounts have the reverse 'has_many' relationship to either its credit or
7
+ # debit entries
8
+ #
9
+ # @example
10
+ # cash = Plutus::Asset.find_by_name('Cash')
11
+ # accounts_receivable = Plutus::Asset.find_by_name('Accounts Receivable')
12
+ #
13
+ # debit_amount = Plutus::DebitAmount.new(:account => cash, :amount => 1000)
14
+ # credit_amount = Plutus::CreditAmount.new(:account => accounts_receivable, :amount => 1000)
15
+ #
16
+ # entry = Plutus::Entry.new(:description => "Receiving payment on an invoice")
17
+ # entry.debit_amounts << debit_amount
18
+ # entry.credit_amounts << credit_amount
19
+ # entry.save
20
+ #
21
+ # @see http://en.wikipedia.org/wiki/Journal_entry Journal Entry
22
+ #
23
+ # @author Michael Bulat
24
+ class Entry < ActiveRecord::Base
25
+ before_save :default_date
26
+
27
+ if ActiveRecord::VERSION::MAJOR > 4
28
+ belongs_to :commercial_document, :polymorphic => true, optional: true
29
+ else
30
+ belongs_to :commercial_document, :polymorphic => true
31
+ end
32
+ has_many :amounts, class_name: "Plutus::Amount", dependent: :destroy
33
+ has_many :credit_amounts, :extend => AmountsExtension, :class_name => 'Plutus::CreditAmount', :inverse_of => :entry
34
+ has_many :debit_amounts, :extend => AmountsExtension, :class_name => 'Plutus::DebitAmount', :inverse_of => :entry
35
+ has_many :credit_accounts, :through => :credit_amounts, :source => :account, :class_name => 'Plutus::Account'
36
+ has_many :debit_accounts, :through => :debit_amounts, :source => :account, :class_name => 'Plutus::Account'
37
+
38
+ validates_presence_of :description
39
+ validate :has_credit_amounts?
40
+ validate :has_debit_amounts?
41
+ validate :amounts_cancel?
42
+
43
+ # Support construction using 'credits' and 'debits' keys
44
+ accepts_nested_attributes_for :credit_amounts, :debit_amounts, allow_destroy: true
45
+ alias_method :credits=, :credit_amounts_attributes=
46
+ alias_method :debits=, :debit_amounts_attributes=
47
+ # attr_accessible :credits, :debits
48
+
49
+ # Support the deprecated .build method
50
+ def self.build(hash)
51
+ ActiveSupport::Deprecation.warn('Plutus::Transaction.build() is deprecated (use new instead)', caller)
52
+ new(hash)
53
+ end
54
+
55
+ def initialize(*args)
56
+ super
57
+ end
58
+
59
+ private
60
+ def default_date
61
+ todays_date = ActiveRecord::Base.default_timezone == :utc ? Time.now.utc : Time.now
62
+ self.date ||= todays_date
63
+ end
64
+
65
+ def has_credit_amounts?
66
+ errors[:base] << "Entry must have at least one credit amount" if self.credit_amounts.blank?
67
+ end
68
+
69
+ def has_debit_amounts?
70
+ errors[:base] << "Entry must have at least one debit amount" if self.debit_amounts.blank?
71
+ end
72
+
73
+ def amounts_cancel?
74
+ errors[:base] << "The credit and debit amounts are not equal" if credit_amounts.balance_for_new_record != debit_amounts.balance_for_new_record
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,56 @@
1
+ module Plutus
2
+ # The Equity class is an account type used to represents owners rights to the assets.
3
+ #
4
+ # === Normal Balance
5
+ # The normal balance on Equity accounts is a *Credit*.
6
+ #
7
+ # @see http://en.wikipedia.org/wiki/Equity_(finance) Equity
8
+ #
9
+ # @author Michael Bulat
10
+ class Equity < Account
11
+
12
+ self.normal_credit_balance = true
13
+
14
+ # The balance of the account.
15
+ #
16
+ # Equity accounts have normal credit balances, so the debits are subtracted from the credits
17
+ # unless this is a contra account, in which credits are subtracted from debits
18
+ #
19
+ # Takes an optional hash specifying :from_date and :to_date for calculating balances during periods.
20
+ # :from_date and :to_date may be strings of the form "yyyy-mm-dd" or Ruby Date objects
21
+ #
22
+ # @example
23
+ # >> equity.balance({:from_date => "2000-01-01", :to_date => Date.today})
24
+ # => #<BigDecimal:103259bb8,'0.1E4',4(12)>
25
+ #
26
+ # @example
27
+ # >> equity.balance
28
+ # => #<BigDecimal:103259bb8,'0.2E4',4(12)>
29
+ #
30
+ # @return [BigDecimal] The decimal value balance
31
+ def balance(options={})
32
+ super
33
+ end
34
+
35
+ # This class method is used to return
36
+ # the balance of all Equity accounts.
37
+ #
38
+ # Contra accounts are automatically subtracted from the balance.
39
+ #
40
+ # Takes an optional hash specifying :from_date and :to_date for calculating balances during periods.
41
+ # :from_date and :to_date may be strings of the form "yyyy-mm-dd" or Ruby Date objects
42
+ #
43
+ # @example
44
+ # >> Plutus::Equity.balance({:from_date => "2000-01-01", :to_date => Date.today})
45
+ # => #<BigDecimal:103259bb8,'0.1E4',4(12)>
46
+ #
47
+ # @example
48
+ # >> Plutus::Equity.balance
49
+ # => #<BigDecimal:1030fcc98,'0.82875E5',8(20)>
50
+ #
51
+ # @return [BigDecimal] The decimal value balance
52
+ def self.balance(options={})
53
+ super
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,56 @@
1
+ module Plutus
2
+ # The Expense class is an account type used to represents assets or services consumed in the generation of revenue.
3
+ #
4
+ # === Normal Balance
5
+ # The normal balance on Expense accounts is a *Debit*.
6
+ #
7
+ # @see http://en.wikipedia.org/wiki/Expense Expenses
8
+ #
9
+ # @author Michael Bulat
10
+ class Expense < Account
11
+
12
+ self.normal_credit_balance = false
13
+
14
+ # The balance of the account.
15
+ #
16
+ # Expenses have normal debit balances, so the credits are subtracted from the debits
17
+ # unless this is a contra account, in which debits are subtracted from credits
18
+ #
19
+ # Takes an optional hash specifying :from_date and :to_date for calculating balances during periods.
20
+ # :from_date and :to_date may be strings of the form "yyyy-mm-dd" or Ruby Date objects
21
+ #
22
+ # @example
23
+ # >> expense.balance({:from_date => "2000-01-01", :to_date => Date.today})
24
+ # => #<BigDecimal:103259bb8,'0.1E4',4(12)>
25
+ #
26
+ # @example
27
+ # >> expense.balance
28
+ # => #<BigDecimal:103259bb8,'0.2E4',4(12)>
29
+ #
30
+ # @return [BigDecimal] The decimal value balance
31
+ def balance(options={})
32
+ super
33
+ end
34
+
35
+ # This class method is used to return
36
+ # the balance of all Expense accounts.
37
+ #
38
+ # Contra accounts are automatically subtracted from the balance.
39
+ #
40
+ # Takes an optional hash specifying :from_date and :to_date for calculating balances during periods.
41
+ # :from_date and :to_date may be strings of the form "yyyy-mm-dd" or Ruby Date objects
42
+ #
43
+ # @example
44
+ # >> Plutus::Expense.balance({:from_date => "2000-01-01", :to_date => Date.today})
45
+ # => #<BigDecimal:103259bb8,'0.1E4',4(12)>
46
+ #
47
+ # @example
48
+ # >> Plutus::Expense.balance
49
+ # => #<BigDecimal:1030fcc98,'0.82875E5',8(20)>
50
+ #
51
+ # @return [BigDecimal] The decimal value balance
52
+ def self.balance(options={})
53
+ super
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,56 @@
1
+ module Plutus
2
+ # The Liability class is an account type used to represents debts owed to outsiders.
3
+ #
4
+ # === Normal Balance
5
+ # The normal balance on Liability accounts is a *Credit*.
6
+ #
7
+ # @see http://en.wikipedia.org/wiki/Liability_(financial_accounting) Liability
8
+ #
9
+ # @author Michael Bulat
10
+ class Liability < Account
11
+
12
+ self.normal_credit_balance = true
13
+
14
+ # The balance of the account.
15
+ #
16
+ # Liability accounts have normal credit balances, so the debits are subtracted from the credits
17
+ # unless this is a contra account, in which credits are subtracted from debits
18
+ #
19
+ # Takes an optional hash specifying :from_date and :to_date for calculating balances during periods.
20
+ # :from_date and :to_date may be strings of the form "yyyy-mm-dd" or Ruby Date objects
21
+ #
22
+ # @example
23
+ # >> liability.balance({:from_date => "2000-01-01", :to_date => Date.today})
24
+ # => #<BigDecimal:103259bb8,'0.1E4',4(12)>
25
+ #
26
+ # @example
27
+ # >> liability.balance
28
+ # => #<BigDecimal:103259bb8,'0.2E4',4(12)>
29
+ #
30
+ # @return [BigDecimal] The decimal value balance
31
+ def balance(options={})
32
+ super
33
+ end
34
+
35
+ # This class method is used to return
36
+ # the balance of all Liability accounts.
37
+ #
38
+ # Contra accounts are automatically subtracted from the balance.
39
+ #
40
+ # Takes an optional hash specifying :from_date and :to_date for calculating balances during periods.
41
+ # :from_date and :to_date may be strings of the form "yyyy-mm-dd" or Ruby Date objects
42
+ #
43
+ # @example
44
+ # >> Plutus::Liability.balance({:from_date => "2000-01-01", :to_date => Date.today})
45
+ # => #<BigDecimal:103259bb8,'0.1E4',4(12)>
46
+ #
47
+ # @example
48
+ # >> Plutus::Liability.balance
49
+ # => #<BigDecimal:1030fcc98,'0.82875E5',8(20)>
50
+ #
51
+ # @return [BigDecimal] The decimal value balance
52
+ def self.balance(options={})
53
+ super
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,9 @@
1
+ module Plutus
2
+ module NoTenancy
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ validates :name, presence: true, uniqueness: true
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,56 @@
1
+ module Plutus
2
+ # The Revenue class is an account type used to represents increases in owners equity.
3
+ #
4
+ # === Normal Balance
5
+ # The normal balance on Revenue accounts is a *Credit*.
6
+ #
7
+ # @see http://en.wikipedia.org/wiki/Revenue Revenue
8
+ #
9
+ # @author Michael Bulat
10
+ class Revenue < Account
11
+
12
+ self.normal_credit_balance = true
13
+
14
+ # The balance of the account.
15
+ #
16
+ # Revenue accounts have normal credit balances, so the debits are subtracted from the credits
17
+ # unless this is a contra account, in which credits are subtracted from debits
18
+ #
19
+ # Takes an optional hash specifying :from_date and :to_date for calculating balances during periods.
20
+ # :from_date and :to_date may be strings of the form "yyyy-mm-dd" or Ruby Date objects
21
+ #
22
+ # @example
23
+ # >> revenue.balance({:from_date => "2000-01-01", :to_date => Date.today})
24
+ # => #<BigDecimal:103259bb8,'0.1E4',4(12)>
25
+ #
26
+ # @example
27
+ # >> revenue.balance
28
+ # => #<BigDecimal:103259bb8,'0.2E4',4(12)>
29
+ #
30
+ # @return [BigDecimal] The decimal value balance
31
+ def balance(options={})
32
+ super
33
+ end
34
+
35
+ # This class method is used to return
36
+ # the balance of all Revenue accounts.
37
+ #
38
+ # Contra accounts are automatically subtracted from the balance.
39
+ #
40
+ # Takes an optional hash specifying :from_date and :to_date for calculating balances during periods.
41
+ # :from_date and :to_date may be strings of the form "yyyy-mm-dd" or Ruby Date objects
42
+ #
43
+ # @example
44
+ # >> Plutus::Revenue.balance({:from_date => "2000-01-01", :to_date => Date.today})
45
+ # => #<BigDecimal:103259bb8,'0.1E4',4(12)>
46
+ #
47
+ # @example
48
+ # >> Plutus::Revenue.balance
49
+ # => #<BigDecimal:1030fcc98,'0.82875E5',8(20)>
50
+ #
51
+ # @return [BigDecimal] The decimal value balance
52
+ def self.balance(options={})
53
+ super
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,15 @@
1
+ module Plutus
2
+ module Tenancy
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ validates :name, presence: true, uniqueness: { scope: :tenant_id }
7
+
8
+ if ActiveRecord::VERSION::MAJOR > 4
9
+ belongs_to :tenant, class_name: Plutus.tenant_class, optional: true
10
+ else
11
+ belongs_to :tenant, class_name: Plutus.tenant_class
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ <%# Rails flash messages styled for Bootstrap 3.0 %>
2
+ <% flash.each do |name, msg| %>
3
+ <% if msg.is_a?(String) %>
4
+ <div class="alert alert-<%= name.to_s == 'notice' ? 'success' : 'danger' %>">
5
+ <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
6
+ <%= content_tag :div, msg, :id => "flash_#{name}" %>
7
+ </div>
8
+ <% end %>
9
+ <% end %>
@@ -0,0 +1,19 @@
1
+ <%# navigation styled for Bootstrap 3.0 %>
2
+ <nav class="navbar navbar-default navbar-fixed-top">
3
+ <div class="container">
4
+ <div class="navbar-header">
5
+ <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
6
+ <span class="sr-only">Toggle navigation</span>
7
+ <span class="icon-bar"></span>
8
+ <span class="icon-bar"></span>
9
+ <span class="icon-bar"></span>
10
+ </button>
11
+ <a class="navbar-brand" href="/">&nbsp;Plutus</a>
12
+ </div>
13
+ <div class="collapse navbar-collapse">
14
+ <ul class="nav navbar-nav">
15
+ <%= render 'layouts/plutus/navigation_links' %>
16
+ </ul>
17
+ </div>
18
+ </div>
19
+ </nav>
@@ -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>Plutus</title>
6
+ <%= stylesheet_link_tag "plutus/application", media: "all" %>
7
+ <%= javascript_include_tag "plutus/application" %>
8
+ <%= csrf_meta_tags %>
9
+ </head>
10
+ <body>
11
+ <header>
12
+ <%= render 'layouts/plutus/navigation' %>
13
+ </header>
14
+ <main role="main">
15
+ <%= render 'layouts/plutus/messages' %>
16
+ <%= yield %>
17
+ </main>
18
+ </body>
19
+ </html>
@@ -0,0 +1,26 @@
1
+ <div class="container">
2
+ <center>
3
+ <h1>General Ledger</h1>
4
+ <br>
5
+ </center>
6
+
7
+ <table class="table table-striped table-hover">
8
+ <tr>
9
+ <th>Name</th>
10
+ <th>Type</th>
11
+ <th>Credit Balance</th>
12
+ <th>Debit Balance</th>
13
+ <th>Balance</td>
14
+ </tr>
15
+
16
+ <% @accounts.each do |account| %>
17
+ <tr class="<%= cycle("even", "odd") -%>">
18
+ <td><%=h account.name %></td>
19
+ <td><%=h account.type.sub('Plutus::','') %></td>
20
+ <td><%=h account.credits_balance.round(2) %></td>
21
+ <td><%=h account.debits_balance.round(2) %></td>
22
+ <td><%=h account.balance.round(2) %></td>
23
+ </tr>
24
+ <% end %>
25
+ </table>
26
+ </div>