bean_sprout 0.0.3 → 0.0.4
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/lib/bean_sprout/account.rb +33 -18
- data/lib/bean_sprout/entry.rb +23 -9
- data/lib/bean_sprout/forwardable_delegate.rb +24 -0
- data/lib/bean_sprout/ledger.rb +129 -0
- data/lib/bean_sprout/package_private.rb +41 -0
- data/lib/bean_sprout/sparse_array.rb +33 -0
- data/lib/bean_sprout/transaction.rb +70 -12
- data/lib/bean_sprout/version.rb +1 -1
- data/lib/bean_sprout.rb +1 -3
- metadata +5 -4
- data/lib/bean_sprout/glass_jar.rb +0 -123
- data/lib/bean_sprout/struct_archive_mixin.rb +0 -16
- data/lib/bean_sprout/struct_from_hash_mixin.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8f8703dcac93814b06f78ef5c7f6081d41e3809c
|
4
|
+
data.tar.gz: 3d50d400de7ff74305f88db06a0feef6c6816658
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 73181700e7e1a3e20b552bc4010cdd4820718fc19c7990968183fad0e8f3e4aa99a49b043099e261e5a60556b06a7d5e56de2744516f54babbb0776dcba93c41
|
7
|
+
data.tar.gz: 85fb4800498552ed1a3a5f3b491c07456467044f048682ea3198387bef22f1ff407634449f8723ca9991d5646939242f7c58fd9b9a9c7c0edc24559b76e32757
|
data/lib/bean_sprout/account.rb
CHANGED
@@ -1,31 +1,46 @@
|
|
1
|
-
require 'bean_sprout/
|
2
|
-
require 'bean_sprout/struct_archive_mixin'
|
1
|
+
require 'bean_sprout/package_private'
|
3
2
|
|
4
3
|
module BeanSprout
|
5
|
-
|
6
|
-
|
7
|
-
include
|
4
|
+
# TODO: abstract :id?
|
5
|
+
class Bean
|
6
|
+
include PackagePrivate::InternalClass
|
8
7
|
|
9
|
-
|
10
|
-
|
8
|
+
attr_reader :id, :balance, :currency, :sprouts
|
9
|
+
|
10
|
+
define_public_interface :Account
|
11
11
|
|
12
|
-
def initialize
|
13
|
-
|
14
|
-
@
|
15
|
-
|
12
|
+
def initialize id, currency
|
13
|
+
@id = id
|
14
|
+
@currency = currency
|
15
|
+
|
16
|
+
@sprouts = Set.new
|
17
|
+
@balance = 0
|
16
18
|
end
|
17
19
|
|
18
|
-
def
|
19
|
-
@
|
20
|
-
@balance
|
20
|
+
def grow sprout
|
21
|
+
@sprouts.add sprout
|
22
|
+
@balance += sprout.amount
|
21
23
|
end
|
22
24
|
|
23
|
-
def
|
24
|
-
@
|
25
|
+
def pick sprout
|
26
|
+
@sprouts.delete sprout
|
27
|
+
@balance -= sprout.amount
|
25
28
|
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Public interface.
|
32
|
+
class Account < PackagePrivate::PublicInterfaceBase
|
33
|
+
def_default_delegators :balance, :currency
|
34
|
+
def_private_default_delegators :sprouts
|
26
35
|
|
27
|
-
def
|
28
|
-
|
36
|
+
def entries
|
37
|
+
sprouts.map do |sprout|
|
38
|
+
if block_given?
|
39
|
+
yield sprout.to_entry
|
40
|
+
else
|
41
|
+
sprout.to_entry
|
42
|
+
end
|
43
|
+
end
|
29
44
|
end
|
30
45
|
end
|
31
46
|
end
|
data/lib/bean_sprout/entry.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
require 'bean_sprout/
|
2
|
-
require 'bean_sprout/struct_archive_mixin'
|
1
|
+
require 'bean_sprout/package_private'
|
3
2
|
require 'bigdecimal'
|
4
3
|
require 'bigdecimal/util'
|
5
4
|
|
@@ -10,16 +9,31 @@ module BeanSprout
|
|
10
9
|
# 2. The amount to be added to the account balance, in local currency;
|
11
10
|
# 3. Convention rate from local currency to the base currency;
|
12
11
|
# 4. Other arbitrary data.
|
13
|
-
class
|
14
|
-
include
|
15
|
-
|
12
|
+
class Sprout
|
13
|
+
include PackagePrivate::InternalClass
|
14
|
+
attr_reader :id, :bean, :amount, :rate
|
16
15
|
|
17
|
-
|
18
|
-
|
16
|
+
define_public_interface :Entry
|
17
|
+
|
18
|
+
def initialize id, bean, amount, rate = 1
|
19
|
+
@id = id
|
20
|
+
@bean = bean
|
21
|
+
@amount = amount.to_d
|
22
|
+
@rate = rate
|
23
|
+
end
|
24
|
+
|
25
|
+
def unified_amount
|
26
|
+
amount * rate
|
19
27
|
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Public Interface.
|
31
|
+
class Entry < PackagePrivate::PublicInterfaceBase
|
32
|
+
def_default_delegators :amount, :unified_amount, :rate
|
33
|
+
def_private_default_delegators :bean
|
20
34
|
|
21
|
-
def
|
22
|
-
|
35
|
+
def account
|
36
|
+
bean.to_account
|
23
37
|
end
|
24
38
|
end
|
25
39
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module BeanSprout
|
4
|
+
class ForwardableDelegate
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
def initialize obj
|
8
|
+
@target = obj
|
9
|
+
end
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def def_default_delegators *args
|
13
|
+
def_delegators :@target, *args
|
14
|
+
end
|
15
|
+
|
16
|
+
def def_private_default_delegators *args
|
17
|
+
def_default_delegators *args
|
18
|
+
private *args
|
19
|
+
end
|
20
|
+
|
21
|
+
private :def_default_delegators, :def_private_default_delegators
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
require 'bean_sprout/sparse_array'
|
2
|
+
require 'bean_sprout/account'
|
3
|
+
require 'bean_sprout/entry'
|
4
|
+
require 'bean_sprout/transaction'
|
5
|
+
|
6
|
+
module BeanSprout
|
7
|
+
class Ledger
|
8
|
+
attr_reader :base_currency
|
9
|
+
|
10
|
+
def initialize base_currency
|
11
|
+
@base_currency = base_currency
|
12
|
+
|
13
|
+
@beans = SparseArray.new
|
14
|
+
@sprout_bunches = SparseArray.new
|
15
|
+
@sprouts = SparseArray.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_account currency, other_data: nil
|
19
|
+
bean = @beans.store do |next_id|
|
20
|
+
Bean.new(next_id, currency)
|
21
|
+
end
|
22
|
+
|
23
|
+
Account.new(bean, other_data)
|
24
|
+
end
|
25
|
+
|
26
|
+
def create_entry account, amount, rate = nil, other_data: nil
|
27
|
+
bean = get_target account
|
28
|
+
if not @beans.has_key? bean.id
|
29
|
+
raise "Unkown account #{bean.to_account} refered."
|
30
|
+
end
|
31
|
+
|
32
|
+
if not (rate or bean.currency == base_currency)
|
33
|
+
raise "Rate must be specified if account is not in base currency " +
|
34
|
+
"#{base_currency}."
|
35
|
+
end
|
36
|
+
rate ||= 1
|
37
|
+
|
38
|
+
|
39
|
+
sprout = @sprouts.store do |next_id|
|
40
|
+
Sprout.new(next_id, bean, amount, rate)
|
41
|
+
end
|
42
|
+
|
43
|
+
Entry.new(sprout, other_data)
|
44
|
+
end
|
45
|
+
|
46
|
+
def create_transaction entries, other_data: nil
|
47
|
+
sprouts = entries.map do |entry| get_target entry end
|
48
|
+
sprout_bunch = @sprout_bunches.store do |next_id|
|
49
|
+
SproutBunch.new(next_id, sprouts)
|
50
|
+
end
|
51
|
+
|
52
|
+
Transaction.new(sprout_bunch, other_data)
|
53
|
+
end
|
54
|
+
|
55
|
+
def transfer from_acc, to_acc, amount
|
56
|
+
if from_acc.currency != @base_currency || to_acc.currency != @base_currency
|
57
|
+
raise "Cannot transfer between two forex accounts."
|
58
|
+
end
|
59
|
+
|
60
|
+
entry0 = create_entry from_acc, -amount
|
61
|
+
entry1 = create_entry to_acc, amount
|
62
|
+
commit_entries [entry0, entry1]
|
63
|
+
end
|
64
|
+
|
65
|
+
def base_currency_forex_transfer from_acc, to_acc, from_amount, to_amount
|
66
|
+
raise "Amount can't be 0." unless from_amount != 0 && to_amount != 0
|
67
|
+
|
68
|
+
rate0 = rate1 = nil
|
69
|
+
if from_acc.currency == @base_currency
|
70
|
+
rate1 = from_amount / to_amount
|
71
|
+
elsif to_acc.currency == @base_currency
|
72
|
+
rate0 = to_amount / from_amount
|
73
|
+
else
|
74
|
+
raise "Forex transfer must be to or from an account of base currency."
|
75
|
+
end
|
76
|
+
|
77
|
+
entry0 = create_entry from_acc, -from_amount, rate0
|
78
|
+
entry1 = create_entry to_acc, to_amount, rate1
|
79
|
+
commit_entries [entry0, entry1]
|
80
|
+
end
|
81
|
+
|
82
|
+
# TODO: clients can't access ID.
|
83
|
+
def account id
|
84
|
+
@beans.fetch(id).to_account
|
85
|
+
end
|
86
|
+
|
87
|
+
# TODO: clients can't access ID.
|
88
|
+
def transaction id
|
89
|
+
@sprout_bunches.fetch(id).to_transaction
|
90
|
+
end
|
91
|
+
|
92
|
+
# TODO: test
|
93
|
+
def accounts
|
94
|
+
@beans.values.map do |bean|
|
95
|
+
if block_given?
|
96
|
+
yield bean.to_account
|
97
|
+
else
|
98
|
+
bean.to_account
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# TODO: test
|
104
|
+
def transactions
|
105
|
+
@sprout_bunches.values.map do |sprout_bunch|
|
106
|
+
if block_given?
|
107
|
+
yield sprout_bunch.to_transaction
|
108
|
+
else
|
109
|
+
sprout_bunch.to_transaction
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def dummy_account
|
115
|
+
@dummy_account ||= create_account @base_currency, other_data: "This is a dummy account."
|
116
|
+
end
|
117
|
+
|
118
|
+
private
|
119
|
+
def get_target obj
|
120
|
+
obj.instance_variable_get :@target
|
121
|
+
end
|
122
|
+
|
123
|
+
def commit_entries entries
|
124
|
+
trans = create_transaction entries
|
125
|
+
trans.commit
|
126
|
+
trans
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'bean_sprout/forwardable_delegate'
|
2
|
+
|
3
|
+
module BeanSprout
|
4
|
+
# Implements the concept of package private methods.
|
5
|
+
module PackagePrivate
|
6
|
+
# A module to be included by the delegatee.
|
7
|
+
module InternalClass
|
8
|
+
# The public interface, set by PublicInterfaceBase.
|
9
|
+
attr_reader :public_interface
|
10
|
+
|
11
|
+
def self.included klass
|
12
|
+
klass.extend ClassMethods
|
13
|
+
end
|
14
|
+
|
15
|
+
def bind_public_interface public_interface
|
16
|
+
raise "Cannot bind public interface to null." if public_interface.nil?
|
17
|
+
raise "Cannot bind public interface twice." unless @public_interface.nil?
|
18
|
+
@public_interface = public_interface
|
19
|
+
end
|
20
|
+
|
21
|
+
module ClassMethods
|
22
|
+
def define_public_interface klass_name
|
23
|
+
define_method "to_#{(klass_name.to_s.split "::").last.downcase}" do
|
24
|
+
@public_interface
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# A base class for delegator classes.
|
31
|
+
class PublicInterfaceBase < ForwardableDelegate
|
32
|
+
def initialize obj, other_data = nil
|
33
|
+
super(obj)
|
34
|
+
obj.bind_public_interface self
|
35
|
+
@other_data = other_data
|
36
|
+
end
|
37
|
+
|
38
|
+
attr_accessor :other_data
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module BeanSprout
|
4
|
+
class SparseArray
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
def_delegators :@entities, :each, :has_key?, :each_value, :values
|
8
|
+
|
9
|
+
def initialize index_offset = 0
|
10
|
+
@entities = {}
|
11
|
+
@index = index_offset
|
12
|
+
end
|
13
|
+
|
14
|
+
def store
|
15
|
+
index = next_index
|
16
|
+
@entities[index] = yield index
|
17
|
+
end
|
18
|
+
|
19
|
+
def fetch index
|
20
|
+
@entities[index]
|
21
|
+
end
|
22
|
+
|
23
|
+
def fetch! index
|
24
|
+
raise "Unkown index #{index}." unless @entities.has_key? index
|
25
|
+
fetch index
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
def next_index
|
30
|
+
@index += 1
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -1,29 +1,87 @@
|
|
1
|
-
require 'bean_sprout/
|
1
|
+
require 'bean_sprout/package_private'
|
2
2
|
|
3
3
|
module BeanSprout
|
4
|
-
class
|
5
|
-
include
|
6
|
-
include StructArchiveMixin
|
4
|
+
class SproutBunch
|
5
|
+
include PackagePrivate::InternalClass
|
7
6
|
|
8
|
-
|
9
|
-
|
7
|
+
attr_reader :sprouts
|
8
|
+
|
9
|
+
define_public_interface :Transaction
|
10
|
+
|
11
|
+
class NotBalancedError < StandardError
|
12
|
+
end
|
13
|
+
|
14
|
+
class IllegalStateError < StandardError
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize id, sprouts
|
18
|
+
@id = id
|
19
|
+
@sprouts = sprouts
|
20
|
+
end
|
10
21
|
|
11
|
-
public
|
12
22
|
def balanced?
|
13
23
|
balance = 0
|
14
|
-
|
15
|
-
balance +=
|
24
|
+
@sprouts.each do |sprout|
|
25
|
+
balance += sprout.unified_amount
|
16
26
|
end
|
17
27
|
balance == 0
|
18
28
|
end
|
19
29
|
|
20
30
|
def balanced!
|
21
|
-
raise "#{
|
31
|
+
raise NotBalancedError.new("#{@sprouts} not balanced.") unless balanced?
|
32
|
+
end
|
33
|
+
|
34
|
+
def plant
|
35
|
+
balanced!
|
36
|
+
raise IllegalStateError, "Can't plant twice." if @in_place
|
37
|
+
sprouts.each do |sprout|
|
38
|
+
sprout.bean.grow sprout
|
39
|
+
end
|
40
|
+
@in_place = true
|
41
|
+
end
|
42
|
+
|
43
|
+
def remove
|
44
|
+
balanced!
|
45
|
+
raise IllegalStateError, "Must plant before remove." unless @in_place
|
46
|
+
sprouts.each do |sprout|
|
47
|
+
sprout.bean.pick sprout
|
48
|
+
end
|
49
|
+
@in_place = false
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class Transaction < PackagePrivate::PublicInterfaceBase
|
54
|
+
def_default_delegators :balanced?
|
55
|
+
def_private_default_delegators :sprouts, :plant, :remove
|
56
|
+
|
57
|
+
def commit
|
58
|
+
begin
|
59
|
+
plant
|
60
|
+
rescue SproutBunch::NotBalancedError
|
61
|
+
raise "Cannot commit an imbalance transaction."
|
62
|
+
rescue SproutBunch::IllegalStateError
|
63
|
+
raise "Cannot commit a transaction more than once."
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def revert
|
68
|
+
begin
|
69
|
+
remove
|
70
|
+
rescue SproutBunch::NotBalancedError
|
71
|
+
raise "Cannot revert an imbalance transaction."
|
72
|
+
rescue SproutBunch::IllegalStateError
|
73
|
+
raise "Cannot revert a transaction more than once."
|
74
|
+
end
|
22
75
|
end
|
23
76
|
|
24
77
|
def entries
|
25
|
-
|
78
|
+
sprouts.map do |sprout|
|
79
|
+
if block_given?
|
80
|
+
yield sprout.to_entry
|
81
|
+
else
|
82
|
+
sprout.to_entry
|
83
|
+
end
|
84
|
+
end
|
26
85
|
end
|
27
86
|
end
|
28
87
|
end
|
29
|
-
|
data/lib/bean_sprout/version.rb
CHANGED
data/lib/bean_sprout.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
require 'bean_sprout/account'
|
2
2
|
require 'bean_sprout/entry'
|
3
|
-
require 'bean_sprout/
|
4
|
-
require 'bean_sprout/struct_archive_mixin'
|
5
|
-
require 'bean_sprout/struct_from_hash_mixin'
|
3
|
+
require 'bean_sprout/ledger'
|
6
4
|
require 'bean_sprout/transaction'
|
7
5
|
require 'bean_sprout/version'
|
8
6
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bean_sprout
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Liqing Muyi
|
@@ -64,9 +64,10 @@ files:
|
|
64
64
|
- lib/bean_sprout.rb
|
65
65
|
- lib/bean_sprout/account.rb
|
66
66
|
- lib/bean_sprout/entry.rb
|
67
|
-
- lib/bean_sprout/
|
68
|
-
- lib/bean_sprout/
|
69
|
-
- lib/bean_sprout/
|
67
|
+
- lib/bean_sprout/forwardable_delegate.rb
|
68
|
+
- lib/bean_sprout/ledger.rb
|
69
|
+
- lib/bean_sprout/package_private.rb
|
70
|
+
- lib/bean_sprout/sparse_array.rb
|
70
71
|
- lib/bean_sprout/transaction.rb
|
71
72
|
- lib/bean_sprout/version.rb
|
72
73
|
homepage: http://github.com/muyiliqing/bean_sprout
|
@@ -1,123 +0,0 @@
|
|
1
|
-
module BeanSprout
|
2
|
-
class GlassJar
|
3
|
-
# TODO: maybe each transaction can have its own
|
4
|
-
# currency.
|
5
|
-
attr_reader :base_currency
|
6
|
-
|
7
|
-
def initialize base_currency
|
8
|
-
@base_currency = base_currency
|
9
|
-
|
10
|
-
@accounts = {}
|
11
|
-
@account_id = 0
|
12
|
-
@account_external_ids = {}
|
13
|
-
|
14
|
-
@transactions = {}
|
15
|
-
@transaction_id = 0
|
16
|
-
|
17
|
-
@entries = {}
|
18
|
-
end
|
19
|
-
|
20
|
-
def open_account account
|
21
|
-
account.archive_in_glass_jar self, next_account_id
|
22
|
-
@accounts[account.id] = account
|
23
|
-
@account_external_ids[account.external_id] = account
|
24
|
-
end
|
25
|
-
|
26
|
-
def create_account currency, external_id = nil, other_data: nil
|
27
|
-
account = Account.new currency, external_id, other_data
|
28
|
-
open_account account
|
29
|
-
end
|
30
|
-
|
31
|
-
def accounts
|
32
|
-
@accounts.values
|
33
|
-
end
|
34
|
-
|
35
|
-
def account id
|
36
|
-
@accounts[id]
|
37
|
-
end
|
38
|
-
|
39
|
-
def account_for external_id
|
40
|
-
@account_external_ids[external_id]
|
41
|
-
end
|
42
|
-
|
43
|
-
def transactions
|
44
|
-
@transactions.values
|
45
|
-
end
|
46
|
-
|
47
|
-
def transaction id
|
48
|
-
@transactions[id]
|
49
|
-
end
|
50
|
-
|
51
|
-
def entries
|
52
|
-
@entries.values
|
53
|
-
end
|
54
|
-
|
55
|
-
def entry id
|
56
|
-
@entries[id]
|
57
|
-
end
|
58
|
-
|
59
|
-
AccountEntitySizeBits = 30
|
60
|
-
def commit_transaction trans
|
61
|
-
raise "Creating transaction with no entries." if trans.entries.empty?
|
62
|
-
if trans.entries.size >= (1 << AccountEntitySizeBits)
|
63
|
-
raise "Creating transaction with too many entries."
|
64
|
-
end
|
65
|
-
|
66
|
-
# Validate trans status.
|
67
|
-
trans.entries.each do |entry|
|
68
|
-
valid_account! entry.account
|
69
|
-
valid_rate! entry
|
70
|
-
end
|
71
|
-
trans.balanced!
|
72
|
-
|
73
|
-
trans.archive_in_glass_jar self, next_transaction_id
|
74
|
-
trans.entries.each_with_index do |entry, index|
|
75
|
-
entry_id = (trans.id << AccountEntitySizeBits) + index
|
76
|
-
entry.archive_in_glass_jar self, entry_id
|
77
|
-
|
78
|
-
@entries[entry_id] = entry
|
79
|
-
account(entry.account).append_entry(entry)
|
80
|
-
end
|
81
|
-
@transactions[trans.id] = trans
|
82
|
-
end
|
83
|
-
|
84
|
-
def create_transaction *entries, other_data: nil
|
85
|
-
trans = Transaction.new(entries, other_data)
|
86
|
-
commit_transaction(trans)
|
87
|
-
end
|
88
|
-
|
89
|
-
def new_account *args
|
90
|
-
Account.new args
|
91
|
-
end
|
92
|
-
|
93
|
-
def new_transaction *args
|
94
|
-
Transaction.new args
|
95
|
-
end
|
96
|
-
|
97
|
-
def new_entry *args
|
98
|
-
Entry.new args
|
99
|
-
end
|
100
|
-
|
101
|
-
private
|
102
|
-
def next_account_id
|
103
|
-
@account_id += 1
|
104
|
-
end
|
105
|
-
|
106
|
-
def next_transaction_id
|
107
|
-
@transaction_id += 1
|
108
|
-
end
|
109
|
-
|
110
|
-
def valid_account! account
|
111
|
-
if not @accounts.has_key? account
|
112
|
-
raise "Unkown account #{account} refered."
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
def valid_rate! entry
|
117
|
-
if not (entry.rate or account(entry.account).currency == base_currency)
|
118
|
-
raise "Rate must be specified if entry is not in base currency " +
|
119
|
-
"#{base_currency}.\n Entry is #{entry}"
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
module BeanSprout
|
2
|
-
module StructArchiveMixin
|
3
|
-
def self.included klass
|
4
|
-
klass.class_eval do
|
5
|
-
attr_reader :id
|
6
|
-
attr_reader :glass_jar
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
def archive_in_glass_jar glass_jar, id
|
11
|
-
@glass_jar = glass_jar
|
12
|
-
@id = id
|
13
|
-
freeze
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|