diff --git a/internal/storage/ledger/transactions.go b/internal/storage/ledger/transactions.go index ac76a033f..60ba5ca0a 100644 --- a/internal/storage/ledger/transactions.go +++ b/internal/storage/ledger/transactions.go @@ -260,7 +260,7 @@ func (s *Store) CommitTransaction(ctx context.Context, tx *ledger.Transaction) e } } - postCommitVolumes, err := s.updateVolumes(ctx, volumeUpdates(tx)...) + postCommitVolumes, err := s.updateVolumes(ctx, tx.VolumeUpdates()...) if err != nil { return errors.Wrap(err, "failed to update balances") } @@ -559,46 +559,3 @@ func filterAccountAddressOnTransactions(address string, source, destination bool return strings.Join(parts, " or ") } } - -func volumeUpdates(transaction *ledger.Transaction) []ledger.AccountsVolumes { - aggregatedVolumes := make(map[string]map[string][]ledger.Posting) - for _, posting := range transaction.Postings { - if _, ok := aggregatedVolumes[posting.Source]; !ok { - aggregatedVolumes[posting.Source] = make(map[string][]ledger.Posting) - } - aggregatedVolumes[posting.Source][posting.Asset] = append(aggregatedVolumes[posting.Source][posting.Asset], posting) - - if posting.Source == posting.Destination { - continue - } - - if _, ok := aggregatedVolumes[posting.Destination]; !ok { - aggregatedVolumes[posting.Destination] = make(map[string][]ledger.Posting) - } - aggregatedVolumes[posting.Destination][posting.Asset] = append(aggregatedVolumes[posting.Destination][posting.Asset], posting) - } - - ret := make([]ledger.AccountsVolumes, 0) - for account, movesByAsset := range aggregatedVolumes { - for asset, postings := range movesByAsset { - volumes := ledger.NewEmptyVolumes() - for _, posting := range postings { - if account == posting.Source { - volumes.Output.Add(volumes.Output, posting.Amount) - } - if account == posting.Destination { - volumes.Input.Add(volumes.Input, posting.Amount) - } - } - - ret = append(ret, ledger.AccountsVolumes{ - Account: account, - Asset: asset, - Input: volumes.Input, - Output: volumes.Output, - }) - } - } - - return ret -} diff --git a/internal/transaction.go b/internal/transaction.go index 923d506ed..129371d8c 100644 --- a/internal/transaction.go +++ b/internal/transaction.go @@ -110,6 +110,50 @@ func (tx Transaction) InvolvedAccounts() []string { return slices.Compact(ret) } +// todo: add unit tests! +func (tx Transaction) VolumeUpdates() []AccountsVolumes { + aggregatedVolumes := make(map[string]map[string][]Posting) + for _, posting := range tx.Postings { + if _, ok := aggregatedVolumes[posting.Source]; !ok { + aggregatedVolumes[posting.Source] = make(map[string][]Posting) + } + aggregatedVolumes[posting.Source][posting.Asset] = append(aggregatedVolumes[posting.Source][posting.Asset], posting) + + if posting.Source == posting.Destination { + continue + } + + if _, ok := aggregatedVolumes[posting.Destination]; !ok { + aggregatedVolumes[posting.Destination] = make(map[string][]Posting) + } + aggregatedVolumes[posting.Destination][posting.Asset] = append(aggregatedVolumes[posting.Destination][posting.Asset], posting) + } + + ret := make([]AccountsVolumes, 0) + for account, movesByAsset := range aggregatedVolumes { + for asset, postings := range movesByAsset { + volumes := NewEmptyVolumes() + for _, posting := range postings { + if account == posting.Source { + volumes.Output.Add(volumes.Output, posting.Amount) + } + if account == posting.Destination { + volumes.Input.Add(volumes.Input, posting.Amount) + } + } + + ret = append(ret, AccountsVolumes{ + Account: account, + Asset: asset, + Input: volumes.Input, + Output: volumes.Output, + }) + } + } + + return ret +} + func (tx Transaction) MarshalJSON() ([]byte, error) { type Aux Transaction type Ret struct {