plutus 0.11.0 → 0.16

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 (64) hide show
  1. checksums.yaml +5 -5
  2. data/README.markdown +66 -40
  3. data/app/assets/javascripts/plutus/application.js +5 -4
  4. data/app/assets/javascripts/plutus/reports.js +5 -0
  5. data/app/assets/stylesheets/bootstrap-theme.min.css +5 -0
  6. data/app/assets/stylesheets/bootstrap.min.css +5 -0
  7. data/app/assets/stylesheets/plutus/application.css +11 -5
  8. data/app/controllers/plutus/accounts_controller.rb +1 -16
  9. data/app/controllers/plutus/application_controller.rb +4 -0
  10. data/app/controllers/plutus/entries_controller.rb +7 -17
  11. data/app/controllers/plutus/reports_controller.rb +40 -0
  12. data/app/models/plutus/account.rb +92 -7
  13. data/app/models/plutus/amount.rb +2 -11
  14. data/app/models/plutus/amounts_extension.rb +31 -6
  15. data/app/models/plutus/asset.rb +21 -18
  16. data/app/models/plutus/entry.rb +15 -3
  17. data/app/models/plutus/equity.rb +22 -19
  18. data/app/models/plutus/expense.rb +21 -18
  19. data/app/models/plutus/liability.rb +27 -19
  20. data/app/models/plutus/revenue.rb +22 -19
  21. data/app/models/plutus/tenancy.rb +5 -1
  22. data/app/views/layouts/plutus/_messages.html.erb +9 -0
  23. data/app/views/layouts/plutus/_navigation.html.erb +19 -0
  24. data/app/views/layouts/plutus/_navigation_links.html.erb +5 -0
  25. data/app/views/layouts/plutus/application.html.erb +19 -0
  26. data/app/views/plutus/accounts/index.html.erb +9 -12
  27. data/app/views/plutus/entries/index.html.erb +22 -11
  28. data/app/views/plutus/reports/_account.html.erb +28 -0
  29. data/app/views/plutus/reports/balance_sheet.html.erb +21 -0
  30. data/app/views/plutus/reports/income_statement.html.erb +24 -0
  31. data/config/routes.rb +6 -3
  32. data/{lib/generators/plutus/templates/migration.rb → db/migrate/20160422010135_create_plutus_tables.rb} +6 -10
  33. data/lib/generators/plutus/add_date_upgrade_generator.rb +11 -0
  34. data/lib/generators/plutus/base_generator.rb +19 -0
  35. data/lib/generators/plutus/plutus_generator.rb +8 -22
  36. data/lib/generators/plutus/templates/add_date_migration.rb +12 -0
  37. data/lib/generators/plutus/templates/tenant_migration.rb +1 -1
  38. data/lib/generators/plutus/templates/update_migration.rb +2 -2
  39. data/lib/generators/plutus/tenancy_generator.rb +2 -17
  40. data/lib/generators/plutus/upgrade_plutus_generator.rb +6 -22
  41. data/lib/plutus.rb +2 -5
  42. data/lib/plutus/engine.rb +5 -0
  43. data/lib/plutus/version.rb +1 -1
  44. data/spec/controllers/accounts_controller_spec.rb +11 -20
  45. data/spec/controllers/entries_controller_spec.rb +11 -20
  46. data/spec/controllers/reports_controller_spec.rb +24 -0
  47. data/spec/factories/account_factory.rb +6 -6
  48. data/spec/factories/amount_factory.rb +3 -3
  49. data/spec/factories/entry_factory.rb +1 -1
  50. data/spec/factories/tenant_factory.rb +12 -0
  51. data/spec/models/account_spec.rb +71 -8
  52. data/spec/models/amount_spec.rb +6 -1
  53. data/spec/models/entry_spec.rb +35 -63
  54. data/spec/models/tenancy_spec.rb +26 -8
  55. data/spec/routing/accounts_routing_spec.rb +6 -25
  56. data/spec/routing/entries_routing_spec.rb +6 -25
  57. data/spec/spec_helper.rb +4 -2
  58. data/spec/support/account_shared_examples.rb +14 -10
  59. data/spec/support/amount_shared_examples.rb +4 -4
  60. data/spec/support/shoulda_matchers.rb +8 -0
  61. metadata +100 -28
  62. data/app/views/plutus/accounts/show.html.erb +0 -59
  63. data/app/views/plutus/entries/show.html.erb +0 -46
  64. data/spec/schema.rb +0 -31
@@ -12,22 +12,13 @@ module Plutus
12
12
  validates_presence_of :type, :amount, :entry, :account
13
13
  # attr_accessible :account, :account_name, :amount, :entry
14
14
 
15
+ delegate :name, to: :account, prefix: true, allow_nil: true
16
+
15
17
  # Assign an account by name
16
18
  def account_name=(name)
17
19
  self.account = Account.find_by_name!(name)
18
20
  end
19
21
 
20
22
  protected
21
-
22
- # Support constructing amounts with account = "name" syntax
23
- def account_with_name_lookup=(v)
24
- if v.kind_of?(String)
25
- ActiveSupport::Deprecation.warn('Plutus was given an :account String (use account_name instead)', caller)
26
- self.account_name = v
27
- else
28
- self.account_without_name_lookup = v
29
- end
30
- end
31
- alias_method_chain :account=, :name_lookup
32
23
  end
33
24
  end
@@ -2,13 +2,38 @@ module Plutus
2
2
  # Association extension for has_many :amounts relations. Internal.
3
3
  module AmountsExtension
4
4
  # Returns a sum of the referenced Amount objects.
5
- def balance
6
- balance = BigDecimal.new('0')
5
+ #
6
+ # Takes a hash specifying :from_date and :to_date for calculating balances during periods.
7
+ # :from_date and :to_date may be strings of the form "yyyy-mm-dd" or Ruby Date objects
8
+ #
9
+ # This runs the summation in the database, so it only works on persisted records.
10
+ #
11
+ # @example
12
+ # credit_amounts.balance({:from_date => "2000-01-01", :to_date => Date.today})
13
+ # => #<BigDecimal:103259bb8,'0.2E4',4(12)>
14
+ #
15
+ # @return [BigDecimal] The decimal value balance
16
+ def balance(hash={})
17
+ if hash[:from_date] && hash[:to_date]
18
+ from_date = hash[:from_date].kind_of?(Date) ? hash[:from_date] : Date.parse(hash[:from_date])
19
+ to_date = hash[:to_date].kind_of?(Date) ? hash[:to_date] : Date.parse(hash[:to_date])
20
+ includes(:entry).where('plutus_entries.date' => from_date..to_date).sum(:amount)
21
+ else
22
+ sum(:amount)
23
+ end
24
+ end
25
+
26
+ # Returns a sum of the referenced Amount objects.
27
+ #
28
+ # This is used primarly in the validation step in Plutus::Entry
29
+ # in order to ensure that the debit and credits are canceling out.
30
+ #
31
+ # Since this does not use the database for sumation, it may be used on non-persisted records.
32
+ def balance_for_new_record
33
+ balance = BigDecimal('0')
7
34
  each do |amount_record|
8
- if amount_record.amount
9
- balance += amount_record.amount
10
- else
11
- balance = nil
35
+ if amount_record.amount && !amount_record.marked_for_destruction?
36
+ balance += amount_record.amount # unless amount_record.marked_for_destruction?
12
37
  end
13
38
  end
14
39
  return balance
@@ -7,24 +7,29 @@ module Plutus
7
7
  # @see http://en.wikipedia.org/wiki/Asset Assets
8
8
  #
9
9
  # @author Michael Bulat
10
- class Asset < Account
10
+ class Asset < Plutus::Account
11
+
12
+ self.normal_credit_balance = false
11
13
 
12
14
  # The balance of the account.
13
15
  #
14
16
  # Assets have normal debit balances, so the credits are subtracted from the debits
15
17
  # unless this is a contra account, in which debits are subtracted from credits
16
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
+ # >> asset.balance({:from_date => "2000-01-01", :to_date => Date.today})
24
+ # => #<BigDecimal:103259bb8,'0.1E4',4(12)>
25
+ #
17
26
  # @example
18
27
  # >> asset.balance
19
28
  # => #<BigDecimal:103259bb8,'0.2E4',4(12)>
20
29
  #
21
30
  # @return [BigDecimal] The decimal value balance
22
- def balance
23
- unless contra
24
- debits_balance - credits_balance
25
- else
26
- credits_balance - debits_balance
27
- end
31
+ def balance(options={})
32
+ super(options)
28
33
  end
29
34
 
30
35
  # This class method is used to return
@@ -32,22 +37,20 @@ module Plutus
32
37
  #
33
38
  # Contra accounts are automatically subtracted from the balance.
34
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::Asset.balance({:from_date => "2000-01-01", :to_date => Date.today})
45
+ # => #<BigDecimal:103259bb8,'0.1E4',4(12)>
46
+ #
35
47
  # @example
36
48
  # >> Plutus::Asset.balance
37
49
  # => #<BigDecimal:1030fcc98,'0.82875E5',8(20)>
38
50
  #
39
51
  # @return [BigDecimal] The decimal value balance
40
- def self.balance
41
- accounts_balance = BigDecimal.new('0')
42
- accounts = self.all
43
- accounts.each do |asset|
44
- unless asset.contra
45
- accounts_balance += asset.balance
46
- else
47
- accounts_balance -= asset.balance
48
- end
49
- end
50
- accounts_balance
52
+ def self.balance(options={})
53
+ super(options)
51
54
  end
52
55
  end
53
56
  end
@@ -22,7 +22,14 @@ module Plutus
22
22
  #
23
23
  # @author Michael Bulat
24
24
  class Entry < ActiveRecord::Base
25
- belongs_to :commercial_document, :polymorphic => true
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
+
26
33
  has_many :credit_amounts, :extend => AmountsExtension, :class_name => 'Plutus::CreditAmount', :inverse_of => :entry
27
34
  has_many :debit_amounts, :extend => AmountsExtension, :class_name => 'Plutus::DebitAmount', :inverse_of => :entry
28
35
  has_many :credit_accounts, :through => :credit_amounts, :source => :account, :class_name => 'Plutus::Account'
@@ -34,7 +41,7 @@ module Plutus
34
41
  validate :amounts_cancel?
35
42
 
36
43
  # Support construction using 'credits' and 'debits' keys
37
- accepts_nested_attributes_for :credit_amounts, :debit_amounts
44
+ accepts_nested_attributes_for :credit_amounts, :debit_amounts, allow_destroy: true
38
45
  alias_method :credits=, :credit_amounts_attributes=
39
46
  alias_method :debits=, :debit_amounts_attributes=
40
47
  # attr_accessible :credits, :debits
@@ -50,6 +57,11 @@ module Plutus
50
57
  end
51
58
 
52
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
+
53
65
  def has_credit_amounts?
54
66
  errors[:base] << "Entry must have at least one credit amount" if self.credit_amounts.blank?
55
67
  end
@@ -59,7 +71,7 @@ module Plutus
59
71
  end
60
72
 
61
73
  def amounts_cancel?
62
- errors[:base] << "The credit and debit amounts are not equal" if credit_amounts.balance != debit_amounts.balance
74
+ errors[:base] << "The credit and debit amounts are not equal" if credit_amounts.balance_for_new_record != debit_amounts.balance_for_new_record
63
75
  end
64
76
  end
65
77
  end
@@ -7,24 +7,29 @@ module Plutus
7
7
  # @see http://en.wikipedia.org/wiki/Equity_(finance) Equity
8
8
  #
9
9
  # @author Michael Bulat
10
- class Equity < Account
10
+ class Equity < Plutus::Account
11
+
12
+ self.normal_credit_balance = true
11
13
 
12
14
  # The balance of the account.
13
15
  #
14
16
  # Equity accounts have normal credit balances, so the debits are subtracted from the credits
15
17
  # unless this is a contra account, in which credits are subtracted from debits
16
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
+ #
17
26
  # @example
18
- # >> asset.balance
27
+ # >> equity.balance
19
28
  # => #<BigDecimal:103259bb8,'0.2E4',4(12)>
20
29
  #
21
30
  # @return [BigDecimal] The decimal value balance
22
- def balance
23
- unless contra
24
- credits_balance - debits_balance
25
- else
26
- debits_balance - credits_balance
27
- end
31
+ def balance(options={})
32
+ super
28
33
  end
29
34
 
30
35
  # This class method is used to return
@@ -32,22 +37,20 @@ module Plutus
32
37
  #
33
38
  # Contra accounts are automatically subtracted from the balance.
34
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
+ #
35
47
  # @example
36
48
  # >> Plutus::Equity.balance
37
49
  # => #<BigDecimal:1030fcc98,'0.82875E5',8(20)>
38
50
  #
39
51
  # @return [BigDecimal] The decimal value balance
40
- def self.balance
41
- accounts_balance = BigDecimal.new('0')
42
- accounts = self.all
43
- accounts.each do |equity|
44
- unless equity.contra
45
- accounts_balance += equity.balance
46
- else
47
- accounts_balance -= equity.balance
48
- end
49
- end
50
- accounts_balance
52
+ def self.balance(options={})
53
+ super
51
54
  end
52
55
  end
53
56
  end
@@ -7,24 +7,29 @@ module Plutus
7
7
  # @see http://en.wikipedia.org/wiki/Expense Expenses
8
8
  #
9
9
  # @author Michael Bulat
10
- class Expense < Account
10
+ class Expense < Plutus::Account
11
+
12
+ self.normal_credit_balance = false
11
13
 
12
14
  # The balance of the account.
13
15
  #
14
16
  # Expenses have normal debit balances, so the credits are subtracted from the debits
15
17
  # unless this is a contra account, in which debits are subtracted from credits
16
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
+ #
17
26
  # @example
18
27
  # >> expense.balance
19
28
  # => #<BigDecimal:103259bb8,'0.2E4',4(12)>
20
29
  #
21
30
  # @return [BigDecimal] The decimal value balance
22
- def balance
23
- unless contra
24
- debits_balance - credits_balance
25
- else
26
- credits_balance - debits_balance
27
- end
31
+ def balance(options={})
32
+ super
28
33
  end
29
34
 
30
35
  # This class method is used to return
@@ -32,22 +37,20 @@ module Plutus
32
37
  #
33
38
  # Contra accounts are automatically subtracted from the balance.
34
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
+ #
35
47
  # @example
36
48
  # >> Plutus::Expense.balance
37
49
  # => #<BigDecimal:1030fcc98,'0.82875E5',8(20)>
38
50
  #
39
51
  # @return [BigDecimal] The decimal value balance
40
- def self.balance
41
- accounts_balance = BigDecimal.new('0')
42
- accounts = self.all
43
- accounts.each do |expense|
44
- unless expense.contra
45
- accounts_balance += expense.balance
46
- else
47
- accounts_balance -= expense.balance
48
- end
49
- end
50
- accounts_balance
52
+ def self.balance(options={})
53
+ super
51
54
  end
52
55
  end
53
56
  end
@@ -7,42 +7,50 @@ module Plutus
7
7
  # @see http://en.wikipedia.org/wiki/Liability_(financial_accounting) Liability
8
8
  #
9
9
  # @author Michael Bulat
10
- class Liability < Account
10
+ class Liability < Plutus::Account
11
+
12
+ self.normal_credit_balance = true
11
13
 
12
14
  # The balance of the account.
13
15
  #
14
16
  # Liability accounts have normal credit balances, so the debits are subtracted from the credits
15
17
  # unless this is a contra account, in which credits are subtracted from debits
16
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
+ #
17
26
  # @example
18
27
  # >> liability.balance
19
28
  # => #<BigDecimal:103259bb8,'0.2E4',4(12)>
20
29
  #
21
30
  # @return [BigDecimal] The decimal value balance
22
- def balance
23
- unless contra
24
- credits_balance - debits_balance
25
- else
26
- debits_balance - credits_balance
27
- end
31
+ def balance(options={})
32
+ super
28
33
  end
29
34
 
30
- # Balance of all Liability accounts
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)>
31
46
  #
32
47
  # @example
33
48
  # >> Plutus::Liability.balance
34
49
  # => #<BigDecimal:1030fcc98,'0.82875E5',8(20)>
35
- def self.balance
36
- accounts_balance = BigDecimal.new('0')
37
- accounts = self.all
38
- accounts.each do |liability|
39
- unless liability.contra
40
- accounts_balance += liability.balance
41
- else
42
- accounts_balance -= liability.balance
43
- end
44
- end
45
- accounts_balance
50
+ #
51
+ # @return [BigDecimal] The decimal value balance
52
+ def self.balance(options={})
53
+ super
46
54
  end
47
55
  end
48
56
  end
@@ -7,24 +7,29 @@ module Plutus
7
7
  # @see http://en.wikipedia.org/wiki/Revenue Revenue
8
8
  #
9
9
  # @author Michael Bulat
10
- class Revenue < Account
10
+ class Revenue < Plutus::Account
11
+
12
+ self.normal_credit_balance = true
11
13
 
12
14
  # The balance of the account.
13
15
  #
14
16
  # Revenue accounts have normal credit balances, so the debits are subtracted from the credits
15
17
  # unless this is a contra account, in which credits are subtracted from debits
16
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
+ #
17
26
  # @example
18
- # >> asset.balance
27
+ # >> revenue.balance
19
28
  # => #<BigDecimal:103259bb8,'0.2E4',4(12)>
20
29
  #
21
30
  # @return [BigDecimal] The decimal value balance
22
- def balance
23
- unless contra
24
- credits_balance - debits_balance
25
- else
26
- debits_balance - credits_balance
27
- end
31
+ def balance(options={})
32
+ super
28
33
  end
29
34
 
30
35
  # This class method is used to return
@@ -32,22 +37,20 @@ module Plutus
32
37
  #
33
38
  # Contra accounts are automatically subtracted from the balance.
34
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
+ #
35
47
  # @example
36
48
  # >> Plutus::Revenue.balance
37
49
  # => #<BigDecimal:1030fcc98,'0.82875E5',8(20)>
38
50
  #
39
51
  # @return [BigDecimal] The decimal value balance
40
- def self.balance
41
- accounts_balance = BigDecimal.new('0')
42
- accounts = self.all
43
- accounts.each do |revenue|
44
- unless revenue.contra
45
- accounts_balance += revenue.balance
46
- else
47
- accounts_balance -= revenue.balance
48
- end
49
- end
50
- accounts_balance
52
+ def self.balance(options={})
53
+ super
51
54
  end
52
55
  end
53
56
  end