plutus 0.11.0 → 0.16

Sign up to get free protection for your applications and to get access to all the features.
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