@@ -18,102 +18,96 @@ import Instruments: instrument, symbol, amount, name, currency
1818export Credit, Debit, Account, Ledger, Entry, AccountId, AccountInfo
1919export id, balance, credit!, debit!, post!, instrument, symbol, amount, name, currency
2020
21- struct AccountId{T}
22- value:: T
21+ abstract type Identifier end
22+ struct AccountId <: Identifier
23+ value:: UUID
2324end
25+ AccountId () = AccountId (uuid4 ())
2426
25- Base. show (io:: IO , id:: AccountId ) = print (io, id. value)
27+ struct AccountCode
28+ value:: String
29+ end
2630
27- mutable struct Account{P<: Position ,I<: AccountId }
28- id:: I
31+ abstract type AccountType end
32+ struct Credit <: AccountType end
33+ struct Debit <: AccountType end
34+
35+ mutable struct Account{P<: Position }
36+ id:: AccountId
2937 balance:: P
3038end
31- Account (balance:: Position ) = Account (AccountId (uuid4 () ), balance)
39+ Account (balance:: Position ) = Account (AccountId (), balance)
3240
33- # Identity function (to make code more generic)
34- account (v:: Account ) = v
41+ abstract type AccountNode end
42+ struct AccountInfo{AT<: AccountType ,A<: Account } <: AccountNode
43+ account:: A
44+ code:: AccountCode
45+ name:: String
3546
36- id (account:: Account ) = account. id
37- balance (account:: Account ) = account. balance
47+ function AccountInfo (:: Type{T} , account, code, name) where {T<: AccountType }
48+ return new {T} (account, code, name)
49+ end
50+ end
3851
39- instrument (:: Account{P} ) where {P<: Position } = instrument (P)
40- symbol (:: Account{P} ) where {P<: Position } = symbol (P)
41- currency (:: Account{P} ) where {P<: Position } = currency (P)
52+ struct AccountGroup{AT<: AccountType } <: AccountNode
53+ code:: AccountCode
54+ name:: String
55+ parent:: Union{Nothing,AccountGroup{<:AccountType}}
56+ subaccounts:: Vector{AccountInfo}
57+ subgroups:: Vector{AccountGroup}
4258
43- amount (amt:: Account ) = amount (amt. balance)
59+ function AccountGroup (:: Type{T} , account, name, parent= nothing ) where {T<: AccountType }
60+ new {T} (account, code, name, parent, Vector {AccountInfo} (), Vector {AccountGroup} ())
61+ end
62+ end
4463
45- debit! (account:: Account , amt:: Position ) = (account. balance += amt)
46- credit! (account:: Account , amt:: Position ) = (account. balance -= amt)
64+ # Identity function (to make code more generic)
65+ account (acc:: Account ) = acc
66+ account (info:: AccountInfo ) = info. account
4767
48- Base. show (io:: IO , account:: Account ) = print (io, " $(string (id (account))) : $(balance (account)) ." )
68+ account_type (:: Union{AccountInfo{AT},AccountGroup{AT}} ) where {AT} = AT
69+ code (acc:: Union{<:AccountInfo,<:AccountGroup} ) = acc. code
70+ name (acc:: Union{<:AccountInfo,<:AccountGroup} ) = acc. name
4971
50- struct Entry{D,C}
51- debit:: D
52- credit:: C
53- end
72+ parent (group:: AccountGroup ) = group. parent
73+ subaccounts (group:: AccountGroup ) = group. subaccounts
74+ subgroups (group:: AccountGroup ) = group. subgroups
5475
55- Base . show (io :: IO , e :: Entry{<: Account,<:Account} ) =
56- print (io, " Entry: \n " , " Debit: $(e . debit) \n " , " Credit: $(e . credit) " )
76+ id (acc :: Account ) = acc . id
77+ id (info :: AccountInfo ) = id ( account (info) )
5778
58- abstract type AccountType end
59- struct Credit <: AccountType end
60- struct Debit <: AccountType end
79+ balance (acc:: Account ) = acc. balance
80+ balance (info:: AccountInfo ) = balance (account (info))
81+ balance (group:: AccountGroup ) =
82+ sum (map (info-> balance (info), subaccounts (group))) +
83+ sum (map (grp-> balance (grp), subgroups (group)))
6184
62- Base . show (io :: IO , :: Type{Debit } ) = print (io, " Debit " )
63- Base . show (io :: IO , :: Type{Credit} ) = print (io, " Credit " )
85+ instrument ( :: Account{P } ) where {P <: Position } = instrument (P )
86+ instrument (info :: AccountInfo ) = instrument ( account (info) )
6487
65- # SPJ: this does not maintain the distinction we'd talked about, of keeping
66- # all debit accounts and all credit accounts in with separate types.
67- # This will end up doing a lot of processing at run-time, and will be relatively
68- # rather slow compared to what we had discussed.
88+ symbol (:: Account{P} ) where {P<: Position } = symbol (P)
89+ symbol (info:: AccountInfo ) = symbol (account (info))
6990
70- struct AccountInfo{T<: AccountType }
71- account:: Account
72- name:: String
73- parent:: Union{Nothing,AccountInfo}
74- subaccounts:: Vector{AccountInfo}
91+ currency (:: Account{P} ) where {P<: Position } = currency (P)
92+ currency (info:: AccountInfo ) = currency (account (info))
7593
76- function AccountInfo (:: Type{T} , account, name, parent= nothing ) where {T<: AccountType }
77- ag = new {T} (account, name, parent, Vector {AccountInfo} ())
78- (parent === nothing ) || push! (parent. subaccounts, ag)
79- return ag
80- end
81- end
94+ amount (acc:: Account ) = amount (balance (acc))
95+ amount (info:: AccountInfo ) = amount (balance (account (info)))
8296
83- account (info:: AccountInfo ) = info. account
84- name (info:: AccountInfo ) = info. name
85- parent (info:: AccountInfo ) = info. parent
86- subaccounts (info:: AccountInfo ) = info. subaccounts
97+ debit! (acc:: Account , amt:: Position ) = (acc. balance += amt)
98+ credit! (acc:: Account , amt:: Position ) = (acc. balance -= amt)
8799
88- id (info:: AccountInfo ) = id (account (info))
89- balance (info:: AccountInfo{Debit} ) =
90- isempty (subaccounts (info)) ? balance (account (info)) :
91- balance (account (info)) + sum (map (info-> balance (account (info)), subaccounts (info)))
92- balance (info:: AccountInfo{Credit} ) =
93- isempty (subaccounts (info)) ? - balance (account (info)) :
94- - balance (account (info)) - sum (map (info-> balance (account (info)), subaccounts (info)))
100+ struct Entry{D<: Account ,C<: Account }
101+ debit:: D
102+ credit:: C
103+ end
95104
96105function post! (entry:: Entry , amt:: Position )
97106 debit! (account (entry. debit), amt)
98107 credit! (account (entry. credit), amt)
99108 entry
100109end
101110
102- AbstractTrees. children (info:: AccountInfo ) =
103- isempty (subaccounts (info)) ? Vector {AccountInfo} () : subaccounts (info)
104- AbstractTrees. printnode (io:: IO ,info:: AccountInfo ) =
105- print (io, " $(name (info)) ($(id (info)) ): $(balance (info)) " )
106-
107- Base. show (io:: IO ,info:: AccountInfo ) =
108- isempty (subaccounts (info)) ? printnode (io, info) : print_tree (io, info)
109-
110- function Base. show (io:: IO , e:: Entry )
111- print (io,
112- " Entry:\n " ,
113- " Debit: $(name (e. debit)) ($(id (e. debit)) ): $(balance (e. debit)) \n " ,
114- " Credit: $(name (e. credit)) ($(id (e. credit)) ): $(balance (e. credit)) \n " )
115- end
116-
117111struct Ledger{P<: Position ,I<: AccountId }
118112 indexes:: Dict{I,Int}
119113 accounts:: StructArray{Account{P,I}}
@@ -128,15 +122,14 @@ struct Ledger{P<:Position,I<:AccountId}
128122end
129123
130124Base. getindex (ledger:: Ledger , ix) = ledger. accounts[ix]
131-
132125Base. getindex (ledger:: Ledger , id:: AccountId ) =
133126 ledger. accounts[ledger. indexes[id]]
134127Base. getindex (ledger:: Ledger , array:: AbstractVector{<:AccountId} ) =
135128 ledger. accounts[broadcast (id-> ledger. indexes[id], array)]
136129
137- function add_account! (ledger:: Ledger , account :: Account )
138- push! (ledger. accounts, account )
139- ledger. indexes[id (account )] = length (ledger. accounts)
130+ function add_account! (ledger:: Ledger , acc :: Account )
131+ push! (ledger. accounts, acc )
132+ ledger. indexes[id (acc )] = length (ledger. accounts)
140133end
141134
142135# const chartofaccounts = Dict{String,AccountGroup{<:Cash}}()
180173# return newaccount
181174# end
182175
176+ Base. show (io:: IO , id:: Identifier ) = print (io, id. value)
177+ Base. show (io:: IO , code:: AccountCode ) = print (io, code. value)
178+
179+ Base. show (io:: IO , :: Type{Debit} ) = print (io, " Debit" )
180+ Base. show (io:: IO , :: Type{Credit} ) = print (io, " Credit" )
181+
182+ Base. show (io:: IO , acc:: Account ) = print (io, " $(string (id (acc))) : $(balance (acc)) ." )
183+ Base. show (io:: IO , info:: AccountInfo{Debit} ) = print (io, " $(code (info)) - $(name (info)) : $(balance (info)) ." )
184+ Base. show (io:: IO , info:: AccountInfo{Credit} ) = print (io, " $(code (info)) - $(name (info)) : $(- balance (info)) ." )
185+
186+
187+ # AbstractTrees.children(info::AccountInfo) =
188+ # isempty(subaccounts(info)) ? Vector{AccountInfo}() : subaccounts(info)
189+ # AbstractTrees.printnode(io::IO,info::AccountInfo) =
190+ # print(io, "$(name(info)) ($(id(info))): $(balance(info))")
191+
192+ # Base.show(io::IO,info::AccountInfo) =
193+ # isempty(subaccounts(info)) ? printnode(io, info) : print_tree(io, info)
194+
195+ # Base.show(io::IO, e::Entry) =
196+ # print(io, "Entry:\n", " Debit: $(e.debit)\n", " Credit: $(e.credit)")
197+
198+ # function Base.show(io::IO, e::Entry)
199+ # print(io,
200+ # "Entry:\n",
201+ # " Debit: $(name(e.debit)) ($(id(e.debit))): $(balance(e.debit))\n",
202+ # " Credit: $(name(e.credit)) ($(id(e.credit))): $(balance(e.credit))\n")
203+ # end
204+
183205end # module Ledgers
0 commit comments