-
Notifications
You must be signed in to change notification settings - Fork 3
/
Accounting.go
executable file
·142 lines (119 loc) · 4.92 KB
/
Accounting.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package acccore
import (
"context"
"fmt"
"github.com/shopspring/decimal"
"time"
)
// NewAccounting instantiate new Accounting logic modules.
func NewAccounting(accountManager AccountManager, transactionManager TransactionManager, journalManager JournalManager, uniqueIDGenerator UniqueIDGenerator) *Accounting {
return &Accounting{
accountManager: accountManager,
transactionManager: transactionManager,
journalManager: journalManager,
uniqueIDGenerator: uniqueIDGenerator,
}
}
// Accounting is the account detail structure
type Accounting struct {
accountManager AccountManager
transactionManager TransactionManager
journalManager JournalManager
uniqueIDGenerator UniqueIDGenerator
}
// GetAccountManager returns account manager
func (acc *Accounting) GetAccountManager() AccountManager {
return acc.accountManager
}
// GetTransactionManager returns transaction manager
func (acc *Accounting) GetTransactionManager() TransactionManager {
return acc.transactionManager
}
// GetJournalManager returns journal manager
func (acc *Accounting) GetJournalManager() JournalManager {
return acc.journalManager
}
// GetUniqueIDGenerator returns id generator
func (acc *Accounting) GetUniqueIDGenerator() UniqueIDGenerator {
return acc.uniqueIDGenerator
}
// CreateNewAccount creates a new account
func (acc *Accounting) CreateNewAccount(context context.Context, accountNumber, name, description, coa string, currency string, alignment Alignment, creator string) (Account, error) {
account := acc.GetAccountManager().NewAccount(context).
SetName(name).SetDescription(description).SetCOA(coa).
SetCurrency(currency).SetAlignment(alignment).
SetCreateBy(creator).SetCreateTime(time.Now())
if len(accountNumber) == 0 {
account.SetAccountNumber(acc.GetUniqueIDGenerator().NewUniqueID())
} else {
account.SetAccountNumber(accountNumber)
}
err := acc.GetAccountManager().PersistAccount(context, account)
if err != nil {
return nil, err
}
return account, nil
}
// TransactionInfo transaction info details
type TransactionInfo struct {
AccountNumber string
Description string
TxType Alignment
Amount decimal.Decimal
}
// CreateNewJournal creates a new journal
func (acc *Accounting) CreateNewJournal(context context.Context, description string, transactions []TransactionInfo, creator string) (Journal, error) {
journal := acc.GetJournalManager().NewJournal(context).SetDescription(description)
journal.SetJournalID(acc.GetUniqueIDGenerator().NewUniqueID()).SetCreateBy(creator).
SetCreateTime(time.Now()).SetJournalingTime(time.Now()).
SetReversal(false).SetReversedJournal(nil)
transacs := make([]Transaction, 0)
// make sure all Transactions have accounts of the same Currency
for _, txinfo := range transactions {
newTransaction := acc.GetTransactionManager().NewTransaction(context).SetCreateBy(creator).SetCreateTime(time.Now()).
SetDescription(txinfo.Description).SetAccountNumber(txinfo.AccountNumber).SetAmount(txinfo.Amount).
SetTransactionTime(time.Now()).SetAlignment(txinfo.TxType).SetTransactionID(acc.GetUniqueIDGenerator().NewUniqueID())
transacs = append(transacs, newTransaction)
}
journal.SetTransactions(transacs)
err := acc.GetJournalManager().PersistJournal(context, journal)
if err != nil {
err = acc.GetJournalManager().CommitJournal(context, journal)
if err != nil {
err = acc.GetJournalManager().CancelJournal(context, journal)
return nil, err
}
fmt.Println("No error but no content")
return nil, fmt.Errorf("commit journal raised no error but no content")
}
return journal, nil
}
// CreateReversal creats a reversal
func (acc *Accounting) CreateReversal(context context.Context, description string, reversed Journal, creator string) (Journal, error) {
journal := acc.GetJournalManager().NewJournal(context).SetDescription(description)
journal.SetJournalID(acc.GetUniqueIDGenerator().NewUniqueID()).SetCreateBy(creator).SetCreateTime(time.Now()).SetJournalingTime(time.Now()).
SetReversal(true).SetReversedJournal(reversed)
transacs := make([]Transaction, 0)
// make sure all Transactions have accounts of the same Currency
for _, txinfo := range reversed.GetTransactions() {
tx := DEBIT
if txinfo.GetAlignment() == DEBIT {
tx = CREDIT
}
newTransaction := acc.GetTransactionManager().NewTransaction(context).SetCreateBy(creator).SetCreateTime(time.Now()).
SetDescription(fmt.Sprintf("%s - reversed", txinfo.GetDescription())).SetAccountNumber(txinfo.GetAccountNumber()).
SetTransactionTime(time.Now()).SetAlignment(tx).SetTransactionID(acc.GetUniqueIDGenerator().NewUniqueID())
transacs = append(transacs, newTransaction)
}
journal.SetTransactions(transacs)
err := acc.GetJournalManager().PersistJournal(context, journal)
if err != nil {
err = acc.GetJournalManager().CommitJournal(context, journal)
if err != nil {
err = acc.GetJournalManager().CancelJournal(context, journal)
return nil, err
}
return nil, err
}
return journal, nil
}