Twisp 101
Step 4: Organize Accounts for Balance Rollups
Use account sets to group and organize accounts into a chart, taking advantage of the built-in balance aggregations.
With AccountSets, we can collect related accounts to provide an easy interface into summary balances and queries into the entries.
We've already created checking accounts for each customer, but Zuzu also needs a way to summarize all customer accounts so that we can see the total balance.
To accomplish this, we'll create an account set called "Customers" and add the customer accounts to it.
Create customers account set
010_CreateCustomersAccountSet
mutation CreateCustomersAccountSet($customersId: UUID!, $journalId: UUID!) {
createAccountSet(
input: {
accountSetId: $customersId
journalId: $journalId
name: "Customers"
description: "All customer's accounts"
normalBalanceType: CREDIT
}
) {
accountSetId
journalId
name
description
normalBalanceType
}
}
Now that we have an account set, let's add the two customer accounts to it:
011_AddCustomersToSet
mutation AddCustomersToSet(
$customersId: UUID!
$ernieId: UUID!
$bertId: UUID!
) {
addErnie: addToAccountSet(
id: $customersId
member: { memberType: ACCOUNT, memberId: $ernieId }
) {
accountSetId
}
addBert: addToAccountSet(
id: $customersId
member: { memberType: ACCOUNT, memberId: $bertId }
) {
accountSetId
}
}
Now that we have posted several transactions and created an account set, we can look at balances and interrogate their history to see how account balances change with each activity posted to that account.
Review balances & interrogate history
Let's start by querying for the balance of the "Customers" set, as well as the balance of each member account.
013_GetCustomersBalances
query GetCustomersBalances($customersId: UUID!, $journalId: UUID!) {
accountSet(id: $customersId) {
name
balance {
settled {
normalBalance {
units
}
}
}
members(first: 10) {
nodes {
__typename
... on Account {
name
balance(journalId: $journalId) {
settled {
normalBalance {
units
}
}
}
}
}
}
}
}
As expected, the account set's balance is always equal to the sum of its member's balances.
Because records in Twisp are append-only, we can review the history of any record to see how its state changed over time.
Let's query the balance history of Ernie's account and compare it to the entries to see how it changed in response to transactions posted.
014_GetErnieBalanceHistory
query GetErnieBalanceHistory($ernieId: UUID!, $journalId: UUID!) {
account(id: $ernieId) {
name
balance(journalId: $journalId) {
settled {
normalBalance {
units
}
}
version
history(first: 10) {
nodes {
version
settled {
normalBalance {
units
}
}
}
}
}
entries(
where: { journalId: { eq: "822cb59f-ce51-4837-8391-2af3b7a5fc51" } }
first: 10
) {
nodes {
entryType
direction
units
}
}
}
}
Conclusion
That finalizes the tutorial! Let's recap what we did to customize and test an accounting core for the imaginary neobank Zuzu:
- ✅ Modeled accounts for customers, assets, and revenue
- ✅ Designed tran codes for bank transfers as well as ACH credits and debits
- ✅ Organized customer accounts into a set and ran queries against it
- ✅ Interrogated the balance history and entries for an account
We hope that this has been useful for you to understand how Twisp works and what you can build with it. Obviously, this is an oversimplified example. Your product will certainly be more complex (and interesting)!
We'd love to talk with you about your project. If you're interested, please get in touch.