double_entry 1.0.1 → 2.0.0.beta5

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 (79) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +497 -0
  3. data/README.md +107 -44
  4. data/double_entry.gemspec +22 -49
  5. data/lib/active_record/locking_extensions.rb +3 -3
  6. data/lib/active_record/locking_extensions/log_subscriber.rb +1 -1
  7. data/lib/double_entry.rb +29 -21
  8. data/lib/double_entry/account.rb +39 -46
  9. data/lib/double_entry/account_balance.rb +20 -3
  10. data/lib/double_entry/balance_calculator.rb +5 -5
  11. data/lib/double_entry/configurable.rb +1 -0
  12. data/lib/double_entry/configuration.rb +8 -2
  13. data/lib/double_entry/errors.rb +13 -13
  14. data/lib/double_entry/line.rb +7 -6
  15. data/lib/double_entry/locking.rb +5 -5
  16. data/lib/double_entry/transfer.rb +37 -30
  17. data/lib/double_entry/validation.rb +1 -0
  18. data/lib/double_entry/validation/account_fixer.rb +36 -0
  19. data/lib/double_entry/validation/line_check.rb +25 -43
  20. data/lib/double_entry/version.rb +1 -1
  21. data/lib/generators/double_entry/install/install_generator.rb +22 -1
  22. data/lib/generators/double_entry/install/templates/initializer.rb +20 -0
  23. data/lib/generators/double_entry/install/templates/migration.rb +45 -55
  24. metadata +35 -256
  25. data/.gitignore +0 -32
  26. data/.rspec +0 -2
  27. data/.travis.yml +0 -29
  28. data/.yardopts +0 -2
  29. data/Gemfile +0 -2
  30. data/Rakefile +0 -15
  31. data/lib/double_entry/reporting.rb +0 -181
  32. data/lib/double_entry/reporting/aggregate.rb +0 -110
  33. data/lib/double_entry/reporting/aggregate_array.rb +0 -76
  34. data/lib/double_entry/reporting/day_range.rb +0 -42
  35. data/lib/double_entry/reporting/hour_range.rb +0 -45
  36. data/lib/double_entry/reporting/line_aggregate.rb +0 -16
  37. data/lib/double_entry/reporting/line_aggregate_filter.rb +0 -79
  38. data/lib/double_entry/reporting/month_range.rb +0 -94
  39. data/lib/double_entry/reporting/time_range.rb +0 -59
  40. data/lib/double_entry/reporting/time_range_array.rb +0 -49
  41. data/lib/double_entry/reporting/week_range.rb +0 -107
  42. data/lib/double_entry/reporting/year_range.rb +0 -40
  43. data/script/jack_hammer +0 -210
  44. data/script/setup.sh +0 -8
  45. data/spec/active_record/locking_extensions_spec.rb +0 -110
  46. data/spec/double_entry/account_balance_spec.rb +0 -7
  47. data/spec/double_entry/account_spec.rb +0 -130
  48. data/spec/double_entry/balance_calculator_spec.rb +0 -88
  49. data/spec/double_entry/configuration_spec.rb +0 -50
  50. data/spec/double_entry/line_spec.rb +0 -80
  51. data/spec/double_entry/locking_spec.rb +0 -214
  52. data/spec/double_entry/performance/double_entry_performance_spec.rb +0 -32
  53. data/spec/double_entry/performance/reporting/aggregate_performance_spec.rb +0 -50
  54. data/spec/double_entry/reporting/aggregate_array_spec.rb +0 -123
  55. data/spec/double_entry/reporting/aggregate_spec.rb +0 -205
  56. data/spec/double_entry/reporting/line_aggregate_filter_spec.rb +0 -90
  57. data/spec/double_entry/reporting/line_aggregate_spec.rb +0 -39
  58. data/spec/double_entry/reporting/month_range_spec.rb +0 -139
  59. data/spec/double_entry/reporting/time_range_array_spec.rb +0 -169
  60. data/spec/double_entry/reporting/time_range_spec.rb +0 -45
  61. data/spec/double_entry/reporting/week_range_spec.rb +0 -103
  62. data/spec/double_entry/reporting_spec.rb +0 -181
  63. data/spec/double_entry/transfer_spec.rb +0 -93
  64. data/spec/double_entry/validation/line_check_spec.rb +0 -99
  65. data/spec/double_entry_spec.rb +0 -428
  66. data/spec/generators/double_entry/install/install_generator_spec.rb +0 -30
  67. data/spec/spec_helper.rb +0 -118
  68. data/spec/support/accounts.rb +0 -21
  69. data/spec/support/blueprints.rb +0 -43
  70. data/spec/support/database.example.yml +0 -21
  71. data/spec/support/database.travis.yml +0 -24
  72. data/spec/support/double_entry_spec_helper.rb +0 -27
  73. data/spec/support/gemfiles/Gemfile.rails-3.2.x +0 -8
  74. data/spec/support/gemfiles/Gemfile.rails-4.1.x +0 -6
  75. data/spec/support/gemfiles/Gemfile.rails-4.2.x +0 -5
  76. data/spec/support/gemfiles/Gemfile.rails-5.0.x +0 -5
  77. data/spec/support/performance_helper.rb +0 -26
  78. data/spec/support/reporting_configuration.rb +0 -6
  79. data/spec/support/schema.rb +0 -74
@@ -1,30 +0,0 @@
1
- require 'action_controller'
2
- require 'generator_spec/test_case'
3
- require 'generators/double_entry/install/install_generator'
4
-
5
- RSpec.describe DoubleEntry::Generators::InstallGenerator do
6
- include GeneratorSpec::TestCase
7
-
8
- destination File.expand_path('../../../../../tmp', __FILE__)
9
-
10
- before do
11
- prepare_destination
12
- run_generator
13
- end
14
-
15
- specify do
16
- expect(destination_root).to have_structure {
17
- directory 'db' do
18
- directory 'migrate' do
19
- migration 'create_double_entry_tables' do
20
- contains 'class CreateDoubleEntryTable'
21
- contains 'create_table "double_entry_account_balances"'
22
- contains 'create_table "double_entry_lines"'
23
- contains 'create_table "double_entry_line_aggregates"'
24
- contains 'create_table "double_entry_line_checks"'
25
- end
26
- end
27
- end
28
- }
29
- end
30
- end
data/spec/spec_helper.rb DELETED
@@ -1,118 +0,0 @@
1
- # encoding: utf-8
2
- require 'bundler/setup'
3
- require 'active_record'
4
- require 'active_support'
5
-
6
- if ActiveRecord::VERSION::MAJOR < 4
7
- require 'test-unit'
8
- Test::Unit::AutoRunner.need_auto_run = false
9
- end
10
-
11
- db_engine = ENV['DB'] || 'mysql'
12
-
13
- FileUtils.mkdir_p 'tmp'
14
- FileUtils.mkdir_p 'log'
15
- FileUtils.rm 'log/test.log', :force => true
16
-
17
- database_config_file = File.expand_path('../support/database.yml', __FILE__)
18
- if File.exist?(database_config_file)
19
- ActiveRecord::Base.establish_connection YAML.load_file(database_config_file)[db_engine]
20
- else
21
- puts 'Please configure your spec/support/database.yml file.'
22
- puts 'See spec/support/database.example.yml'
23
- exit 1
24
- end
25
-
26
- # Buffered Logger was deprecated in ActiveSupport 4.0.0 and was removed in 4.1.0
27
- # Logger was added in ActiveSupport 4.0.0
28
- if defined? ActiveSupport::Logger
29
- ActiveRecord::Base.logger = ActiveSupport::Logger.new('log/test.log')
30
- else
31
- ActiveRecord::Base.logger = ActiveSupport::BufferedLogger.new('log/test.log')
32
- end
33
-
34
- I18n.config.enforce_available_locales = false
35
-
36
- silence_warnings do
37
- require 'rspec'
38
- require 'rspec/its'
39
- require 'database_cleaner'
40
- require 'machinist/active_record'
41
- require 'timecop'
42
- require 'money'
43
- end
44
-
45
- require 'double_entry'
46
-
47
- Dir[File.expand_path('../support/**/*.rb', __FILE__)].each { |f| require f }
48
-
49
- RSpec.configure do |config|
50
- # rspec-expectations config goes here. You can use an alternate
51
- # assertion/expectation library such as wrong or the stdlib/minitest
52
- # assertions if you prefer.
53
- config.expect_with :rspec do |expectations|
54
- # This option will default to `true` in RSpec 4. It makes the `description`
55
- # and `failure_message` of custom matchers include text for helper methods
56
- # defined using `chain`, e.g.:
57
- # be_bigger_than(2).and_smaller_than(4).description
58
- # # => "be bigger than 2 and smaller than 4"
59
- # ...rather than:
60
- # # => "be bigger than 2"
61
- expectations.include_chain_clauses_in_custom_matcher_descriptions = true
62
- expectations.warn_about_potential_false_positives = false
63
- end
64
-
65
- # rspec-mocks config goes here. You can use an alternate test double
66
- # library (such as bogus or mocha) by changing the `mock_with` option here.
67
- config.mock_with :rspec do |mocks|
68
- # Prevents you from mocking or stubbing a method that does not exist on
69
- # a real object. This is generally recommended, and will default to
70
- # `true` in RSpec 4.
71
- mocks.verify_partial_doubles = true
72
- end
73
-
74
- # These two settings work together to allow you to limit a spec run
75
- # to individual examples or groups you care about by tagging them with
76
- # `:focus` metadata. When nothing is tagged with `:focus`, all examples
77
- # get run.
78
- config.filter_run :focus
79
- config.run_all_when_everything_filtered = true
80
-
81
- # Limits the available syntax to the non-monkey patched syntax that is recommended.
82
- # For more details, see:
83
- # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
84
- # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
85
- # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
86
- config.disable_monkey_patching!
87
-
88
- # Many RSpec users commonly either run the entire suite or an individual
89
- # file, and it's useful to allow more verbose output when running an
90
- # individual spec file.
91
- if config.files_to_run.one?
92
- # Use the documentation formatter for detailed output,
93
- # unless a formatter has already been configured
94
- # (e.g. via a command-line flag).
95
- config.default_formatter = 'doc'
96
- else
97
- config.default_formatter = 'RSpec::Instafail'
98
- end
99
-
100
- # Print the 5 slowest examples and example groups at the
101
- # end of the spec run, to help surface which specs are running
102
- # particularly slow.
103
- config.profile_examples = 5
104
-
105
- config.include DoubleEntrySpecHelper
106
-
107
- config.before(:suite) do
108
- DatabaseCleaner.strategy = :truncation
109
- end
110
-
111
- config.before do
112
- DatabaseCleaner.clean
113
- end
114
-
115
- config.after do
116
- Timecop.return
117
- end
118
- end
@@ -1,21 +0,0 @@
1
- # encoding: utf-8
2
- require_relative 'blueprints'
3
- DoubleEntry.configure do |config|
4
- # A set of accounts to test with
5
- config.define_accounts do |accounts|
6
- user_scope = accounts.active_record_scope_identifier(User)
7
- accounts.define(:identifier => :savings, :scope_identifier => user_scope, :positive_only => true)
8
- accounts.define(:identifier => :checking, :scope_identifier => user_scope, :positive_only => true)
9
- accounts.define(:identifier => :test, :scope_identifier => user_scope)
10
- accounts.define(:identifier => :btc_test, :scope_identifier => user_scope, :currency => 'BTC')
11
- accounts.define(:identifier => :btc_savings, :scope_identifier => user_scope, :currency => 'BTC')
12
- end
13
-
14
- # A set of allowed transfers between accounts
15
- config.define_transfers do |transfers|
16
- transfers.define(:from => :test, :to => :savings, :code => :bonus)
17
- transfers.define(:from => :test, :to => :checking, :code => :pay)
18
- transfers.define(:from => :savings, :to => :test, :code => :test_withdrawal)
19
- transfers.define(:from => :btc_test, :to => :btc_savings, :code => :btc_test_transfer)
20
- end
21
- end
@@ -1,43 +0,0 @@
1
- class UserBlueprint < Machinist::ActiveRecord::Blueprint
2
- def make!(attributes = {})
3
- savings_balance = attributes.delete(:savings_balance)
4
- checking_balance = attributes.delete(:checking_balance)
5
- bitcoin_balance = attributes.delete(:bitcoin_balance)
6
- user = super(attributes)
7
- if savings_balance
8
- DoubleEntry.transfer(
9
- savings_balance,
10
- :from => DoubleEntry.account(:test, :scope => user),
11
- :to => DoubleEntry.account(:savings, :scope => user),
12
- :code => :bonus,
13
- )
14
- end
15
- if checking_balance
16
- DoubleEntry.transfer(
17
- checking_balance,
18
- :from => DoubleEntry.account(:test, :scope => user),
19
- :to => DoubleEntry.account(:checking, :scope => user),
20
- :code => :pay,
21
- )
22
- end
23
- if bitcoin_balance
24
- DoubleEntry.transfer(
25
- bitcoin_balance,
26
- :from => DoubleEntry.account(:btc_test, :scope => user),
27
- :to => DoubleEntry.account(:btc_savings, :scope => user),
28
- :code => :btc_test_transfer,
29
- )
30
- end
31
- user
32
- end
33
- end
34
-
35
- class User < ActiveRecord::Base
36
- def self.blueprint_class
37
- UserBlueprint
38
- end
39
- end
40
-
41
- User.blueprint do
42
- username { "user#{sn}" }
43
- end
@@ -1,21 +0,0 @@
1
- postgres:
2
- host: localhost
3
- adapter: postgresql
4
- encoding: unicode
5
- database: double_entry_test
6
- pool: 100
7
- username: postgres
8
- password:
9
- min_messages: warning
10
- mysql:
11
- adapter: mysql2
12
- encoding: utf8
13
- database: double_entry_test
14
- pool: 100
15
- username: root
16
- password:
17
- sqlite:
18
- adapter: sqlite3
19
- encoding: utf8
20
- database: tmp/double_entry_test.sqlite3
21
- pool: 100
@@ -1,24 +0,0 @@
1
- mysql:
2
- adapter: mysql2
3
- username: root
4
- password:
5
- database: double_entry_test
6
- pool: 100
7
- timeout: 5000
8
- host: 127.0.0.1
9
-
10
- postgres:
11
- adapter: postgresql
12
- username: postgres
13
- password:
14
- database: double_entry_test
15
- min_messages: ERROR
16
- pool: 100
17
- timeout: 5000
18
- host: localhost
19
-
20
- sqlite:
21
- adapter: sqlite3
22
- encoding: utf8
23
- database: tmp/double_entry_test.sqlite3
24
- pool: 100
@@ -1,27 +0,0 @@
1
- # encoding: utf-8
2
- module DoubleEntrySpecHelper
3
- def lines_for_account(account)
4
- lines = DoubleEntry::Line.order(:id)
5
- lines = lines.where(:scope => account.scope_identity) if account.scoped?
6
- lines = lines.where(:account => account.identifier.to_s)
7
- lines
8
- end
9
-
10
- def perform_deposit(user, amount)
11
- DoubleEntry.transfer(
12
- Money.new(amount),
13
- :from => DoubleEntry.account(:test, :scope => user),
14
- :to => DoubleEntry.account(:savings, :scope => user),
15
- :code => :bonus,
16
- )
17
- end
18
-
19
- def perform_btc_deposit(user, amount)
20
- DoubleEntry.transfer(
21
- Money.new(amount, :btc),
22
- :from => DoubleEntry.account(:btc_test, :scope => user),
23
- :to => DoubleEntry.account(:btc_savings, :scope => user),
24
- :code => :btc_test_transfer,
25
- )
26
- end
27
- end
@@ -1,8 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec :path => '../../../'
4
-
5
- gem 'mysql2', '< 0.4'
6
- gem 'i18n', '0.6.11'
7
- gem 'rails', '~> 3.2.0'
8
-
@@ -1,6 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec :path => '../../../'
4
-
5
- gem 'mysql2', '< 0.4'
6
- gem 'rails', '~> 4.1.0'
@@ -1,5 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec :path => '../../../'
4
-
5
- gem 'rails', '~> 4.2.0'
@@ -1,5 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec :path => '../../../'
4
-
5
- gem 'rails', '~> 5.0.0'
@@ -1,26 +0,0 @@
1
- module PerformanceHelper
2
- require 'ruby-prof'
3
-
4
- def start_profiling(measure_mode = RubyProf::PROCESS_TIME)
5
- RubyProf.measure_mode = measure_mode
6
- RubyProf.start
7
- end
8
-
9
- def stop_profiling(profile_name = nil)
10
- result = RubyProf.stop
11
- puts "#{profile_name} Time: #{format('%#.3g', total_time(result))}s"
12
- unless ENV.fetch('CI', false)
13
- if profile_name
14
- outdir = './profiles'
15
- Dir.mkdir(outdir) unless Dir.exist?(outdir)
16
- printer = RubyProf::MultiPrinter.new(result)
17
- printer.print(:path => outdir, :profile => profile_name)
18
- end
19
- end
20
- result
21
- end
22
-
23
- def total_time(result)
24
- result.threads.inject(0) { |time, thread| time + thread.total_time }
25
- end
26
- end
@@ -1,6 +0,0 @@
1
- # encoding: utf-8
2
- RSpec.configure do |config|
3
- config.before do
4
- DoubleEntry::Reporting.instance_variable_set(:@configuration, nil)
5
- end
6
- end
@@ -1,74 +0,0 @@
1
- ActiveRecord::Schema.define do
2
- self.verbose = false
3
-
4
- create_table "double_entry_account_balances", :force => true do |t|
5
- t.string "account", :limit => 31, :null => false
6
- t.string "scope", :limit => 23
7
- t.integer "balance", :null => false
8
- t.timestamps :null => false
9
- end
10
-
11
- add_index "double_entry_account_balances", ["account"], :name => "index_account_balances_on_account"
12
- add_index "double_entry_account_balances", ["scope", "account"], :name => "index_account_balances_on_scope_and_account", :unique => true
13
-
14
- create_table "double_entry_lines", :force => true do |t|
15
- t.string "account", :limit => 31, :null => false
16
- t.string "scope", :limit => 23
17
- t.string "code", :limit => 47, :null => false
18
- t.integer "amount", :null => false
19
- t.integer "balance", :null => false
20
- t.integer "partner_id"
21
- t.string "partner_account", :limit => 31, :null => false
22
- t.string "partner_scope", :limit => 23
23
- t.integer "detail_id"
24
- t.string "detail_type"
25
- t.timestamps :null => false
26
- end
27
-
28
- add_index "double_entry_lines", ["account", "code", "created_at"], :name => "lines_account_code_created_at_idx"
29
- add_index "double_entry_lines", ["account", "created_at"], :name => "lines_account_created_at_idx"
30
- add_index "double_entry_lines", ["scope", "account", "created_at"], :name => "lines_scope_account_created_at_idx"
31
- add_index "double_entry_lines", ["scope", "account", "id"], :name => "lines_scope_account_id_idx"
32
-
33
- create_table "double_entry_line_aggregates", :force => true do |t|
34
- t.string "function", :limit => 15, :null => false
35
- t.string "account", :limit => 31, :null => false
36
- t.string "code", :limit => 47
37
- t.string "scope", :limit => 23
38
- t.integer "year"
39
- t.integer "month"
40
- t.integer "week"
41
- t.integer "day"
42
- t.integer "hour"
43
- t.integer "amount", :null => false
44
- t.string "filter"
45
- t.string "range_type", :limit => 15, :null => false
46
- t.timestamps :null => false
47
- end
48
-
49
- add_index "double_entry_line_aggregates", ["function", "account", "code", "year", "month", "week", "day"], :name => "line_aggregate_idx"
50
-
51
- create_table "double_entry_line_checks", :force => true do |t|
52
- t.integer "last_line_id", :null => false
53
- t.boolean "errors_found", :null => false
54
- t.text "log"
55
- t.timestamps :null => false
56
- end
57
-
58
- create_table "double_entry_line_metadata", :force => true do |t|
59
- t.integer "line_id", :null => false
60
- t.string "key", :limit => 48, :null => false
61
- t.string "value", :limit => 64, :null => false
62
- t.timestamps :null => false
63
- end
64
-
65
- add_index "double_entry_line_metadata", ["line_id", "key", "value"], :name => "lines_meta_line_id_key_value_idx"
66
-
67
- # test table only
68
- create_table "users", :force => true do |t|
69
- t.string "username", :null => false
70
- t.timestamps :null => false
71
- end
72
-
73
- add_index "users", ["username"], :name => "index_users_on_username", :unique => true
74
- end