borutus 0.2.1 → 0.2.2
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.
- checksums.yaml +4 -4
- data/README.md +62 -64
- data/app/models/borutus/account.rb +97 -86
- data/app/models/borutus/amount.rb +9 -4
- data/app/models/borutus/amounts_extension.rb +1 -1
- data/app/services/borutus/accounts/build_running_balance_query.rb +73 -0
- data/db/migrate/20191025095830_add_borutus_amount_counter_cache.rb +15 -0
- data/lib/borutus.rb +1 -0
- data/lib/borutus/version.rb +1 -1
- data/spec/controllers/accounts_controller_spec.rb +1 -1
- data/spec/controllers/entries_controller_spec.rb +1 -1
- data/spec/controllers/reports_controller_spec.rb +1 -1
- data/spec/factories/account_factory.rb +13 -13
- data/spec/factories/amount_factory.rb +13 -13
- data/spec/factories/entry_factory.rb +11 -8
- data/spec/models/account_spec.rb +98 -53
- data/spec/models/amount_spec.rb +1 -1
- data/spec/models/entry_spec.rb +54 -50
- data/spec/models/tenancy_spec.rb +6 -6
- data/spec/routing/entries_routing_spec.rb +1 -1
- data/spec/spec_helper.rb +16 -14
- data/spec/support/account_shared_examples.rb +3 -3
- data/spec/support/amount_shared_examples.rb +1 -1
- data/spec/support/factory_bot_helpers.rb +8 -0
- metadata +44 -25
- data/spec/support/factory_girl_helpers.rb +0 -8
data/spec/models/amount_spec.rb
CHANGED
data/spec/models/entry_spec.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
module Borutus
|
4
4
|
describe Entry do
|
5
|
-
let(:entry) {
|
5
|
+
let(:entry) { FactoryBot.build(:entry) }
|
6
6
|
subject { entry }
|
7
7
|
|
8
8
|
it { is_expected.not_to be_valid }
|
9
9
|
|
10
10
|
context "with credit and debit" do
|
11
|
-
let(:entry) {
|
11
|
+
let(:entry) { FactoryBot.build(:entry_with_credit_and_debit) }
|
12
12
|
it { is_expected.to be_valid }
|
13
13
|
|
14
14
|
it "should require a description" do
|
@@ -18,35 +18,35 @@ module Borutus
|
|
18
18
|
end
|
19
19
|
|
20
20
|
context "with a debit" do
|
21
|
-
before
|
22
|
-
entry.debit_amounts <<
|
23
|
-
|
21
|
+
before do
|
22
|
+
entry.debit_amounts << FactoryBot.build(:debit_amount, entry: entry)
|
23
|
+
end
|
24
24
|
it { is_expected.not_to be_valid }
|
25
25
|
|
26
26
|
context "with an invalid credit" do
|
27
27
|
before {
|
28
|
-
entry.credit_amounts <<
|
28
|
+
entry.credit_amounts << FactoryBot.build(:credit_amount, entry: entry, amount: nil)
|
29
29
|
}
|
30
30
|
it { is_expected.not_to be_valid }
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
34
|
context "with a credit" do
|
35
|
-
before
|
36
|
-
entry.credit_amounts <<
|
37
|
-
|
35
|
+
before do
|
36
|
+
entry.credit_amounts << FactoryBot.build(:credit_amount, entry: entry)
|
37
|
+
end
|
38
38
|
it { is_expected.not_to be_valid }
|
39
39
|
|
40
40
|
context "with an invalid debit" do
|
41
|
-
before
|
42
|
-
entry.debit_amounts <<
|
43
|
-
|
41
|
+
before do
|
42
|
+
entry.debit_amounts << FactoryBot.build(:debit_amount, entry: entry, amount: nil)
|
43
|
+
end
|
44
44
|
it { is_expected.not_to be_valid }
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
48
|
context "without a date" do
|
49
|
-
let(:entry) {
|
49
|
+
let(:entry) { FactoryBot.build(:entry_with_credit_and_debit, date: nil) }
|
50
50
|
|
51
51
|
context "should assign a default date before being saved" do
|
52
52
|
before { entry.save! }
|
@@ -55,44 +55,50 @@ module Borutus
|
|
55
55
|
end
|
56
56
|
|
57
57
|
it "should require the debit and credit amounts to cancel" do
|
58
|
-
entry.credit_amounts <<
|
59
|
-
entry.debit_amounts <<
|
58
|
+
entry.credit_amounts << FactoryBot.build(:credit_amount, amount: 100, entry: entry)
|
59
|
+
entry.debit_amounts << FactoryBot.build(:debit_amount, amount: 200, entry: entry)
|
60
60
|
expect(entry).not_to be_valid
|
61
|
-
expect(entry.errors[
|
61
|
+
expect(entry.errors["base"]).to eq(["The credit and debit amounts are not equal"])
|
62
62
|
end
|
63
63
|
|
64
64
|
it "should require the debit and credit amounts to cancel even with fractions" do
|
65
|
-
entry =
|
66
|
-
entry.credit_amounts <<
|
67
|
-
entry.debit_amounts <<
|
65
|
+
entry = FactoryBot.build(:entry)
|
66
|
+
entry.credit_amounts << FactoryBot.build(:credit_amount, amount: 100.1, entry: entry)
|
67
|
+
entry.debit_amounts << FactoryBot.build(:debit_amount, amount: 100.2, entry: entry)
|
68
68
|
expect(entry).not_to be_valid
|
69
|
-
expect(entry.errors[
|
69
|
+
expect(entry.errors["base"]).to eq(["The credit and debit amounts are not equal"])
|
70
70
|
end
|
71
71
|
|
72
72
|
it "should ignore debit and credit amounts marked for destruction to cancel" do
|
73
|
-
entry.credit_amounts <<
|
74
|
-
debit_amount =
|
73
|
+
entry.credit_amounts << FactoryBot.build(:credit_amount, amount: 100, entry: entry)
|
74
|
+
debit_amount = FactoryBot.build(:debit_amount, amount: 100, entry: entry)
|
75
75
|
debit_amount.mark_for_destruction
|
76
76
|
entry.debit_amounts << debit_amount
|
77
77
|
expect(entry).not_to be_valid
|
78
|
-
expect(entry.errors[
|
78
|
+
expect(entry.errors["base"]).to eq(["The credit and debit amounts are not equal"])
|
79
79
|
end
|
80
80
|
|
81
81
|
it "should have a polymorphic commercial document associations" do
|
82
|
-
mock_document =
|
83
|
-
entry =
|
82
|
+
mock_document = FactoryBot.create(:asset) # one would never do this, but it allows us to not require a migration for the test
|
83
|
+
entry = FactoryBot.build(:entry_with_credit_and_debit, commercial_document: mock_document)
|
84
84
|
entry.save!
|
85
85
|
saved_entry = Entry.find(entry.id)
|
86
86
|
expect(saved_entry.commercial_document).to eq(mock_document)
|
87
87
|
end
|
88
88
|
|
89
89
|
context "given a set of accounts" do
|
90
|
-
let(:mock_document) {
|
91
|
-
let!(:accounts_receivable)
|
92
|
-
|
93
|
-
|
90
|
+
let(:mock_document) { FactoryBot.create(:asset) }
|
91
|
+
let!(:accounts_receivable) do
|
92
|
+
FactoryBot.create(:asset, name: "Accounts Receivable")
|
93
|
+
end
|
94
|
+
let!(:sales_revenue) do
|
95
|
+
FactoryBot.create(:revenue, name: "Sales Revenue")
|
96
|
+
end
|
97
|
+
let!(:sales_tax_payable) do
|
98
|
+
FactoryBot.create(:liability, name: "Sales Tax Payable")
|
99
|
+
end
|
94
100
|
|
95
|
-
shared_examples_for
|
101
|
+
shared_examples_for "a built-from-hash Borutus::Entry" do
|
96
102
|
its(:credit_amounts) { is_expected.not_to be_empty }
|
97
103
|
its(:debit_amounts) { is_expected.not_to be_empty }
|
98
104
|
it { is_expected.to be_valid }
|
@@ -118,31 +124,31 @@ module Borutus
|
|
118
124
|
context "when given a credit/debits hash with :account => Account" do
|
119
125
|
let(:hash) {
|
120
126
|
{
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
127
|
+
description: "Sold some widgets",
|
128
|
+
commercial_document: mock_document,
|
129
|
+
debits: [{ account: accounts_receivable, amount: 50 }],
|
130
|
+
credits: [
|
131
|
+
{ account: sales_revenue, amount: 45 },
|
132
|
+
{ account: sales_tax_payable, amount: 5 },
|
133
|
+
],
|
128
134
|
}
|
129
135
|
}
|
130
|
-
include_examples
|
136
|
+
include_examples "a built-from-hash Borutus::Entry"
|
131
137
|
end
|
132
138
|
|
133
139
|
context "when given a credit/debits hash with :account_name => String" do
|
134
140
|
let(:hash) {
|
135
141
|
{
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
142
|
+
description: "Sold some widgets",
|
143
|
+
commercial_document: mock_document,
|
144
|
+
debits: [{ account_name: accounts_receivable.name, amount: 50 }],
|
145
|
+
credits: [
|
146
|
+
{ account_name: sales_revenue.name, amount: 45 },
|
147
|
+
{ account_name: sales_tax_payable.name, amount: 5 },
|
148
|
+
],
|
143
149
|
}
|
144
150
|
}
|
145
|
-
include_examples
|
151
|
+
include_examples "a built-from-hash Borutus::Entry"
|
146
152
|
end
|
147
153
|
end
|
148
154
|
|
@@ -154,7 +160,7 @@ module Borutus
|
|
154
160
|
after { ::ActiveSupport::Deprecation.silenced = false }
|
155
161
|
|
156
162
|
context "when used at all" do
|
157
|
-
let(:hash) {
|
163
|
+
let(:hash) { {} }
|
158
164
|
|
159
165
|
it("should be deprecated") {
|
160
166
|
# .build is the only thing deprecated
|
@@ -162,9 +168,7 @@ module Borutus
|
|
162
168
|
entry
|
163
169
|
}
|
164
170
|
end
|
165
|
-
|
166
171
|
end
|
167
172
|
end
|
168
|
-
|
169
173
|
end
|
170
174
|
end
|
data/spec/models/tenancy_spec.rb
CHANGED
@@ -10,7 +10,7 @@ module Borutus
|
|
10
10
|
Borutus.enable_tenancy = true
|
11
11
|
Borutus.tenant_class = 'Borutus::Entry'
|
12
12
|
|
13
|
-
|
13
|
+
FactoryBotHelpers.reload()
|
14
14
|
Borutus::Asset.new
|
15
15
|
end
|
16
16
|
|
@@ -23,21 +23,21 @@ module Borutus
|
|
23
23
|
Borutus.enable_tenancy = false
|
24
24
|
Borutus.tenant_class = nil
|
25
25
|
|
26
|
-
|
26
|
+
FactoryBotHelpers.reload()
|
27
27
|
end
|
28
28
|
|
29
29
|
it 'validate uniqueness of name scoped to tenant' do
|
30
|
-
account =
|
30
|
+
account = FactoryBot.create(:asset, tenant_id: 10)
|
31
31
|
|
32
|
-
record =
|
32
|
+
record = FactoryBot.build(:asset, name: account.name, tenant_id: 10)
|
33
33
|
expect(record).not_to be_valid
|
34
34
|
expect(record.errors[:name]).to eq(['has already been taken'])
|
35
35
|
end
|
36
36
|
|
37
37
|
it 'allows same name scoped under a different tenant' do
|
38
|
-
account =
|
38
|
+
account = FactoryBot.create(:asset, tenant_id: 10)
|
39
39
|
|
40
|
-
record =
|
40
|
+
record = FactoryBot.build(:asset, name: account.name, tenant_id: 11)
|
41
41
|
expect(record).to be_valid
|
42
42
|
end
|
43
43
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,38 +1,40 @@
|
|
1
|
-
require
|
1
|
+
require "coveralls"
|
2
2
|
Coveralls.wear!
|
3
3
|
|
4
|
-
require
|
4
|
+
require "pry"
|
5
5
|
|
6
|
-
ENV["RAILS_ENV"] ||=
|
6
|
+
ENV["RAILS_ENV"] ||= "test"
|
7
7
|
|
8
|
-
require File.expand_path(
|
9
|
-
|
8
|
+
require File.expand_path(
|
9
|
+
File.dirname(__FILE__) + "/../fixture_rails_root/config/environment",
|
10
|
+
)
|
11
|
+
require Rails.root.join("db/schema").to_s
|
10
12
|
|
11
|
-
require
|
13
|
+
require "rspec/rails"
|
12
14
|
|
13
|
-
|
15
|
+
$LOAD_PATH << File.expand_path(File.dirname(__FILE__) + "/../lib/")
|
14
16
|
|
15
|
-
require
|
16
|
-
require
|
17
|
+
require "borutus"
|
18
|
+
require "kaminari"
|
17
19
|
|
18
20
|
Dir[
|
19
21
|
File.expand_path(
|
20
|
-
File.join(File.dirname(__FILE__),
|
22
|
+
File.join(File.dirname(__FILE__), "support", "**", "*.rb"),
|
21
23
|
)
|
22
24
|
].each do |f|
|
23
25
|
require f
|
24
26
|
end
|
25
27
|
|
26
|
-
require
|
28
|
+
require "factory_bot"
|
27
29
|
|
28
30
|
borutus_definitions = File.expand_path(
|
29
|
-
File.join(File.dirname(__FILE__),
|
31
|
+
File.join(File.dirname(__FILE__), "factories"),
|
30
32
|
)
|
31
|
-
|
33
|
+
FactoryBot.definition_file_paths << borutus_definitions
|
32
34
|
|
33
35
|
RSpec.configure do |config|
|
34
36
|
config.use_transactional_fixtures = true
|
35
37
|
config.infer_spec_type_from_file_location!
|
36
38
|
end
|
37
39
|
|
38
|
-
|
40
|
+
FactoryBotHelpers.reload
|
@@ -1,6 +1,6 @@
|
|
1
1
|
shared_examples_for 'a Borutus::Account subtype' do |elements|
|
2
2
|
let(:contra) { false }
|
3
|
-
let(:account) {
|
3
|
+
let(:account) { FactoryBot.create(elements[:kind], contra: contra)}
|
4
4
|
subject { account }
|
5
5
|
|
6
6
|
describe "class methods" do
|
@@ -39,7 +39,7 @@ shared_examples_for 'a Borutus::Account subtype' do |elements|
|
|
39
39
|
end
|
40
40
|
|
41
41
|
describe "when given a debit" do
|
42
|
-
before {
|
42
|
+
before { FactoryBot.create(:debit_amount, account: account) }
|
43
43
|
its(:balance) { is_expected.to be.send(debit_condition, 0) }
|
44
44
|
|
45
45
|
describe "on a contra account" do
|
@@ -49,7 +49,7 @@ shared_examples_for 'a Borutus::Account subtype' do |elements|
|
|
49
49
|
end
|
50
50
|
|
51
51
|
describe "when given a credit" do
|
52
|
-
before {
|
52
|
+
before { FactoryBot.create(:credit_amount, account: account) }
|
53
53
|
its(:balance) { is_expected.to be.send(credit_condition, 0) }
|
54
54
|
|
55
55
|
describe "on a contra account" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: borutus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ramon Tayag
|
@@ -9,22 +9,8 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2019-
|
12
|
+
date: 2019-10-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
-
- !ruby/object:Gem::Dependency
|
15
|
-
name: rails
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
17
|
-
requirements:
|
18
|
-
- - ">"
|
19
|
-
- !ruby/object:Gem::Version
|
20
|
-
version: '4.0'
|
21
|
-
type: :runtime
|
22
|
-
prerelease: false
|
23
|
-
version_requirements: !ruby/object:Gem::Requirement
|
24
|
-
requirements:
|
25
|
-
- - ">"
|
26
|
-
- !ruby/object:Gem::Version
|
27
|
-
version: '4.0'
|
28
14
|
- !ruby/object:Gem::Dependency
|
29
15
|
name: jquery-rails
|
30
16
|
requirement: !ruby/object:Gem::Requirement
|
@@ -68,7 +54,35 @@ dependencies:
|
|
68
54
|
- !ruby/object:Gem::Version
|
69
55
|
version: '1.0'
|
70
56
|
- !ruby/object:Gem::Dependency
|
71
|
-
name:
|
57
|
+
name: light-service
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 0.11.0
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 0.11.0
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: rails
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '4.0'
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '4.0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: shoulda-matchers
|
72
86
|
requirement: !ruby/object:Gem::Requirement
|
73
87
|
requirements:
|
74
88
|
- - ">="
|
@@ -82,7 +96,7 @@ dependencies:
|
|
82
96
|
- !ruby/object:Gem::Version
|
83
97
|
version: '0'
|
84
98
|
- !ruby/object:Gem::Dependency
|
85
|
-
name:
|
99
|
+
name: yard
|
86
100
|
requirement: !ruby/object:Gem::Requirement
|
87
101
|
requirements:
|
88
102
|
- - ">="
|
@@ -95,11 +109,14 @@ dependencies:
|
|
95
109
|
- - ">="
|
96
110
|
- !ruby/object:Gem::Version
|
97
111
|
version: '0'
|
98
|
-
description:
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
112
|
+
description: |2-
|
113
|
+
|
114
|
+
The borutus plugin provides a complete double entry accounting system for
|
115
|
+
use in any Ruby on Rails application. The plugin follows general Double
|
116
|
+
Entry Bookkeeping practices. All calculations are done using BigDecimal
|
117
|
+
in order to prevent floating point rounding errors. The plugin requires
|
118
|
+
a decimal type on your database as well.
|
119
|
+
%
|
103
120
|
email:
|
104
121
|
- ramon.tayag@gmail.com
|
105
122
|
- ace.subido@gmail.com
|
@@ -134,6 +151,7 @@ files:
|
|
134
151
|
- app/models/borutus/no_tenancy.rb
|
135
152
|
- app/models/borutus/revenue.rb
|
136
153
|
- app/models/borutus/tenancy.rb
|
154
|
+
- app/services/borutus/accounts/build_running_balance_query.rb
|
137
155
|
- app/views/borutus/accounts/index.html.erb
|
138
156
|
- app/views/borutus/entries/index.html.erb
|
139
157
|
- app/views/borutus/reports/_account.html.erb
|
@@ -151,6 +169,7 @@ files:
|
|
151
169
|
- config/secret_token.rb
|
152
170
|
- config/session_store.rb
|
153
171
|
- db/migrate/20160422010135_create_borutus_tables.rb
|
172
|
+
- db/migrate/20191025095830_add_borutus_amount_counter_cache.rb
|
154
173
|
- lib/borutus.rb
|
155
174
|
- lib/borutus/engine.rb
|
156
175
|
- lib/borutus/version.rb
|
@@ -186,7 +205,7 @@ files:
|
|
186
205
|
- spec/support/account_shared_examples.rb
|
187
206
|
- spec/support/active_support_helpers.rb
|
188
207
|
- spec/support/amount_shared_examples.rb
|
189
|
-
- spec/support/
|
208
|
+
- spec/support/factory_bot_helpers.rb
|
190
209
|
- spec/support/shoulda_matchers.rb
|
191
210
|
homepage: http://github.com/bloom-solutions/borutus
|
192
211
|
licenses: []
|
@@ -237,5 +256,5 @@ test_files:
|
|
237
256
|
- spec/support/account_shared_examples.rb
|
238
257
|
- spec/support/active_support_helpers.rb
|
239
258
|
- spec/support/amount_shared_examples.rb
|
240
|
-
- spec/support/
|
259
|
+
- spec/support/factory_bot_helpers.rb
|
241
260
|
- spec/support/shoulda_matchers.rb
|