Class: Twobook::Account
- Inherits:
-
Object
show all
- Defined in:
- lib/twobook/account.rb
Constant Summary
collapse
- ACCOUNT_TYPES =
%i(assets liabilities revenue expenses records)
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
Constructor Details
#initialize(balance: 0, **data) ⇒ Account
Returns a new instance of Account.
7
8
9
10
11
12
13
14
15
16
17
18
|
# File 'lib/twobook/account.rb', line 7
def initialize(balance: 0, **data)
@balance = Twobook.wrap_number(balance)
@entries = []
@data = data
@name = define_name
valid_data = self.class.name_includes + self.class.has
data.keys.each do |key|
raise "Invalid data #{key} for #{self.class.category}" unless key.in?(valid_data)
end
end
|
Instance Attribute Details
#balance ⇒ Object
Returns the value of attribute balance.
5
6
7
|
# File 'lib/twobook/account.rb', line 5
def balance
@balance
end
|
#data ⇒ Object
Returns the value of attribute data.
5
6
7
|
# File 'lib/twobook/account.rb', line 5
def data
@data
end
|
#entries ⇒ Object
Returns the value of attribute entries.
5
6
7
|
# File 'lib/twobook/account.rb', line 5
def entries
@entries
end
|
#ledger ⇒ Object
Returns the value of attribute ledger.
5
6
7
|
# File 'lib/twobook/account.rb', line 5
def ledger
@ledger
end
|
#name ⇒ Object
Returns the value of attribute name.
5
6
7
|
# File 'lib/twobook/account.rb', line 5
def name
@name
end
|
Returns the value of attribute tags.
5
6
7
|
# File 'lib/twobook/account.rb', line 5
def tags
@tags
end
|
Class Method Details
.account_type(*args) ⇒ Object
122
123
124
125
126
127
128
|
# File 'lib/twobook/account.rb', line 122
def self.account_type(*args)
return @account_type if args.empty?
unless args.first.in?(ACCOUNT_TYPES)
raise "Invalid account type #{args.first} for #{name}. Valid types: #{ACCOUNT_TYPES}"
end
@account_type = args.first
end
|
.category ⇒ Object
97
98
99
|
# File 'lib/twobook/account.rb', line 97
def self.category
name.underscore.gsub("#{Twobook.configuration.accounting_namespace.underscore}/accounts/", '')
end
|
.description(*args) ⇒ Object
148
149
150
151
152
|
# File 'lib/twobook/account.rb', line 148
def self.description(*args)
@description ||= ''
return @description if args.empty?
@description = args.first
end
|
.from_name(name) ⇒ Object
101
102
103
104
105
106
107
108
|
# File 'lib/twobook/account.rb', line 101
def self.from_name(name)
category_part = name.split(':').first
match = types.detect do |t|
t.name =~ /#{category_part.camelize}$/
end
raise "Bad account name: #{name}" unless match
match
end
|
.has(*args) ⇒ Object
142
143
144
145
146
|
# File 'lib/twobook/account.rb', line 142
def self.has(*args)
@has ||= []
return @has if args.empty?
@has += args
end
|
.name_includes(*args) ⇒ Object
130
131
132
133
134
|
# File 'lib/twobook/account.rb', line 130
def self.name_includes(*args)
@name_includes ||= []
return @name_includes if args.empty?
@name_includes += args
end
|
.tagged?(tag) ⇒ Boolean
114
115
116
117
118
119
120
|
# File 'lib/twobook/account.rb', line 114
def self.tagged?(tag)
if tag.is_a?(Array)
tag.empty? || tag.all? { |t| tagged?(t) }
else
tags.include?(tag)
end
end
|
136
137
138
139
140
|
# File 'lib/twobook/account.rb', line 136
def self.tags(*args)
@tags ||= []
return @tags if args.empty?
@tags += args
end
|
Instance Method Details
#+(other) ⇒ Object
37
38
39
|
# File 'lib/twobook/account.rb', line 37
def +(other)
clone << other
end
|
#<<(other) ⇒ Object
27
28
29
30
31
32
33
34
35
|
# File 'lib/twobook/account.rb', line 27
def <<(other)
raise 'Can only append entries to accounts' unless other.is_a?(Entry)
@entries << other
@entries.sort_by!(&:event)
@balance = Twobook.wrap_number(@balance + other.amount)
update_mutable_data(other.data)
self
end
|
#==(other) ⇒ Object
Also known as:
eql?
Account equality is based only on name, which must be unique
83
84
85
|
# File 'lib/twobook/account.rb', line 83
def ==(other)
@name == other.name
end
|
#balance_before(time) ⇒ Object
55
56
57
58
59
60
|
# File 'lib/twobook/account.rb', line 55
def balance_before(time)
@entries.reduce(0) do |running_total, entry|
return running_total if entry.event.happened_at >= time
running_total + entry.amount
end
end
|
#balance_before_event(event) ⇒ Object
41
42
43
44
45
46
|
# File 'lib/twobook/account.rb', line 41
def balance_before_event(event)
@entries.reduce(0) do |running_total, entry|
return running_total if entry.event >= event
running_total + entry.amount
end
end
|
#clone ⇒ Object
20
21
22
23
24
25
|
# File 'lib/twobook/account.rb', line 20
def clone
c = super
c.instance_variable_set(:@entries, @entries.map(&:clone))
c.instance_variable_set(:@data, @data.deep_dup)
c
end
|
#data_before(time) ⇒ Object
62
63
64
65
66
67
|
# File 'lib/twobook/account.rb', line 62
def data_before(time)
@entries.reduce(@data.slice(*self.class.name_includes)) do |running_total, entry|
return running_total if entry.event.happened_at >= time
running_total.merge(entry.data)
end
end
|
#data_before_event(event) ⇒ Object
48
49
50
51
52
53
|
# File 'lib/twobook/account.rb', line 48
def data_before_event(event)
@entries.reduce(@data.slice(*self.class.name_includes)) do |running_total, entry|
return running_total if entry.event >= event
running_total.merge(entry.data)
end
end
|
#hash ⇒ Object
88
89
90
|
# File 'lib/twobook/account.rb', line 88
def hash
@name.hash
end
|
#inspect ⇒ Object
92
93
94
95
|
# File 'lib/twobook/account.rb', line 92
def inspect
inspected_balance = @balance.to_f
"<#{self.class.name} @name=#{@name} @balance=#{inspected_balance} entry_count=#{@entries.count}>"
end
|
#update_mutable_data(data) ⇒ Object
69
70
71
72
73
|
# File 'lib/twobook/account.rb', line 69
def update_mutable_data(data)
validate_data_mutable(data)
@data = @data.merge(data).sort.to_h
self
end
|
#validate_data_mutable(new_data) ⇒ Object
75
76
77
78
79
80
|
# File 'lib/twobook/account.rb', line 75
def validate_data_mutable(new_data)
new_data.keys.each do |k|
raise "Attribute #{k} cannot be modified in #{inspect}" if k.in?(self.class.name_includes)
raise "Unknown parameter #{k} given to #{inspect}" unless k.in?(self.class.has)
end
end
|