bookkeeping 0.0.1 → 0.0.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/app/models/bookkeeping/account.rb +0 -7
- data/app/models/bookkeeping/credit_amount.rb +6 -0
- data/app/models/bookkeeping/entry.rb +18 -16
- data/lib/bookkeeping/dsl.rb +31 -18
- data/lib/bookkeeping/engine.rb +2 -0
- data/lib/bookkeeping/proxy.rb +25 -0
- data/lib/bookkeeping/version.rb +1 -1
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c80eee7c8cc61dde2184ffefa1c5c9cc241f82df
|
4
|
+
data.tar.gz: 37d0fede0812a012084e4b1fd30599f68360e009
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 58748ee0ad0b0411f736d4747ae0ee6f9bb9be2b1b8037ab43f7e31d0e547d9e1ecaf2407d30b3565d4c5bb5c50edbad8ea411432ae0fa5d57b24e17a1eb943d
|
7
|
+
data.tar.gz: f9c8cca3d4cb2fca1065dfe91a5bacd3a64b4a5f6a534898fb54a1f41e10fbd3978b996456d9034b9425d1b9c0ebe8976d45af2e7db7491e20803f9b2e870947
|
@@ -22,7 +22,6 @@ module Bookkeeping
|
|
22
22
|
|
23
23
|
# Validations
|
24
24
|
validates :name, presence: true
|
25
|
-
validate :prevent_overdraft, unless: :overdraft_enabled?
|
26
25
|
|
27
26
|
class NotFound < StandardError; end
|
28
27
|
class BadKind < StandardError; end
|
@@ -80,11 +79,5 @@ module Bookkeeping
|
|
80
79
|
def overdraft?
|
81
80
|
balance < 0
|
82
81
|
end
|
83
|
-
|
84
|
-
private
|
85
|
-
|
86
|
-
def prevent_overdraft
|
87
|
-
errors.add(:balance, :overdraft) if balance < 0
|
88
|
-
end
|
89
82
|
end
|
90
83
|
end
|
@@ -15,6 +15,7 @@ module Bookkeeping
|
|
15
15
|
class Entry < ActiveRecord::Base
|
16
16
|
|
17
17
|
belongs_to :transactionable, polymorphic: true
|
18
|
+
belongs_to :rollback_entry, class_name: 'Bookkeeping::Entry'
|
18
19
|
has_many :amounts, dependent: :destroy
|
19
20
|
has_many :debit_amounts, class_name: "Bookkeeping::DebitAmount"
|
20
21
|
has_many :credit_amounts, class_name: "Bookkeeping::CreditAmount"
|
@@ -22,42 +23,43 @@ module Bookkeeping
|
|
22
23
|
validates :transactionable, :description, presence: true
|
23
24
|
validate :has_credit_amounts?
|
24
25
|
validate :has_debit_amounts?
|
25
|
-
validate :
|
26
|
+
validate :amounts_equal?
|
26
27
|
|
27
28
|
def self.prepare(options = {}, &block)
|
28
|
-
new(options)
|
29
|
-
dsl = Bookkeeping::DSL.new(entry)
|
30
|
-
dsl.instance_eval &block
|
31
|
-
dsl.build
|
32
|
-
end
|
29
|
+
Bookkeeping::DSL.new(new(options), &block).build
|
33
30
|
end
|
34
31
|
|
35
|
-
# TODO: not work
|
36
|
-
def rollback
|
32
|
+
# TODO: not work
|
33
|
+
def rollback(ref = nil)
|
37
34
|
tran = self
|
38
|
-
|
35
|
+
inverse_entry = self.class.prepare do
|
39
36
|
tran.debit_amounts.each { |di| debit(di.account, -di.amount) }
|
40
37
|
tran.credit_amounts.each { |ci| credit(ci.account, -ci.amount) }
|
41
38
|
transactionable(ref || tran)
|
42
39
|
description("Rollback of #{tran.description}")
|
43
40
|
end
|
44
|
-
|
45
|
-
|
46
|
-
|
41
|
+
inverse_entry.save!
|
42
|
+
|
43
|
+
unless inverse_entry.new_record?
|
44
|
+
self.rollback_entry = inverse_entry
|
45
|
+
self.save!
|
46
|
+
end
|
47
|
+
|
48
|
+
inverse_entry
|
47
49
|
end
|
48
50
|
|
49
51
|
private
|
50
52
|
|
51
53
|
def has_credit_amounts?
|
52
|
-
errors[:
|
54
|
+
errors[:credit_amounts] << "Entry must have at least one credit amount" if self.credit_amounts.blank?
|
53
55
|
end
|
54
56
|
|
55
57
|
def has_debit_amounts?
|
56
|
-
errors[:
|
58
|
+
errors[:debit_amounts] << "Entry must have at least one debit amount" if self.debit_amounts.blank?
|
57
59
|
end
|
58
60
|
|
59
|
-
def
|
60
|
-
errors[:
|
61
|
+
def amounts_equal?
|
62
|
+
errors[:amounts_equality] << "The credit and debit amounts are not equal" if credit_amounts.to_a.sum(&:amount) != debit_amounts.to_a.sum(&:amount)
|
61
63
|
end
|
62
64
|
end
|
63
65
|
end
|
data/lib/bookkeeping/dsl.rb
CHANGED
@@ -1,45 +1,58 @@
|
|
1
1
|
module Bookkeeping
|
2
2
|
class DSL
|
3
|
-
attr_reader :
|
4
|
-
attr_accessor :entry
|
3
|
+
attr_reader :__debits, :__credits, :__description, :__reference
|
5
4
|
|
6
|
-
def initialize(entry)
|
7
|
-
@
|
8
|
-
@
|
9
|
-
|
5
|
+
def initialize(entry, &block)
|
6
|
+
@__debits = {}
|
7
|
+
@__credits = {}
|
8
|
+
|
9
|
+
self.extend Bookkeeping::Proxy
|
10
|
+
self.caller = block.binding.eval "self"
|
11
|
+
|
12
|
+
@__entry = entry
|
13
|
+
|
14
|
+
instance_eval &block
|
10
15
|
end
|
11
16
|
|
12
17
|
def debit(account, amount)
|
13
|
-
@
|
14
|
-
@
|
15
|
-
@debits[account] += amount
|
18
|
+
@__debits[account] ||= 0
|
19
|
+
@__debits[account] += amount
|
16
20
|
end
|
17
21
|
|
18
22
|
def credit(account, amount)
|
19
|
-
@
|
20
|
-
@
|
21
|
-
@credits[account] += amount
|
23
|
+
@__credits[account] ||= 0
|
24
|
+
@__credits[account] += amount
|
22
25
|
end
|
23
26
|
|
24
27
|
def description(description)
|
25
|
-
@
|
28
|
+
@__description = description
|
26
29
|
end
|
27
30
|
|
28
31
|
def transactionable(transactionable)
|
29
|
-
@
|
32
|
+
@__transactionable = transactionable
|
33
|
+
end
|
34
|
+
|
35
|
+
def entry
|
36
|
+
@__entry
|
37
|
+
end
|
38
|
+
|
39
|
+
def entry=(entry)
|
40
|
+
@__entry = entry
|
30
41
|
end
|
31
42
|
|
32
43
|
def build
|
33
|
-
entry.transactionable = @
|
34
|
-
entry.description = @
|
44
|
+
entry.transactionable = @__transactionable || entry.transactionable
|
45
|
+
entry.description = @__description || entry.description
|
35
46
|
|
36
|
-
|
47
|
+
__debits.each do |account, amount|
|
37
48
|
entry.debit_amounts.build(account: account, amount: amount)
|
38
49
|
end
|
39
50
|
|
40
|
-
|
51
|
+
__credits.each do |account, amount|
|
41
52
|
entry.credit_amounts.build(account: account, amount: amount)
|
42
53
|
end
|
54
|
+
|
55
|
+
entry
|
43
56
|
end
|
44
57
|
|
45
58
|
end
|
data/lib/bookkeeping/engine.rb
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
module Bookkeeping
|
2
|
+
module Proxy
|
3
|
+
def caller= context
|
4
|
+
@caller = context
|
5
|
+
exec_in_caller(context)
|
6
|
+
end
|
7
|
+
|
8
|
+
def method_missing(name, *args, &block)
|
9
|
+
@caller.send(name, *args, &block)
|
10
|
+
end
|
11
|
+
|
12
|
+
def respond_to?(name, include_private = false)
|
13
|
+
@caller.respond_to?(name) || super
|
14
|
+
end
|
15
|
+
|
16
|
+
def exec_in_caller(context)
|
17
|
+
return unless context
|
18
|
+
|
19
|
+
context.instance_variables.each do |ivar|
|
20
|
+
value_from_caller = context.instance_variable_get(ivar)
|
21
|
+
self.instance_variable_set(ivar, value_from_caller)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/bookkeeping/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bookkeeping
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexander Shlinchak
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-07-
|
11
|
+
date: 2015-07-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -108,6 +108,20 @@ dependencies:
|
|
108
108
|
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: shoulda-matchers
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
111
125
|
description: The goal of this gem is to build accounting (bookkeeping) system for
|
112
126
|
Rails projects using double entry theory.
|
113
127
|
email:
|
@@ -138,6 +152,7 @@ files:
|
|
138
152
|
- lib/bookkeeping.rb
|
139
153
|
- lib/bookkeeping/dsl.rb
|
140
154
|
- lib/bookkeeping/engine.rb
|
155
|
+
- lib/bookkeeping/proxy.rb
|
141
156
|
- lib/bookkeeping/version.rb
|
142
157
|
- lib/generators/bookkeeping/bookkeeping_generator.rb
|
143
158
|
- lib/generators/bookkeeping/templates/migration.rb
|