The :core
module is responsible for Ivy Wallet's core features - accounts, transactions, categories and balance.
Structure
:core:data-model
: the data classes representing Ivy Wallet's domain model.:core:domain
: pure functions, "actions" (write use-cases) and "flows" (read uses-cases) implementing app's domain logic.:core:persistence
: local persistence of the domain data via transformation to "entities" (Room DB and DataStore).:core:ui
: UI components representing the data model and key Ivy Wallet components.:core:exchange-provider
: fetches latest exchange rate via API.
A brief overview at how our app is implemented.
Everything is a transaction! A transaction represents a movement of Value (money, amount + currency). In the real world you can either get money which is TrnType.Income
or spend money - TrnType.Expense
.
Everything in Ivy Wallet is represented using just "Income" and "Expense" transactions.
For a transaction (movement of value) to happen: the value must either come from somewhere (e.g. a pocket with cash when paying your rent) or go to somewhere (e.g. a bank account when receiving your salary).
Simply said, transactions must be stored somewhere and the perfect place for the is the Account.
Your balance is the sum of the balances of your accounts.
balance =
$\Sigma$ of account balances
The balance of an account is the sum of all Income (+) and Expense (-) transactions that have ever happened.
account balance =
$\Sigma$ of incomes -$\Sigma$ of expenses
The final piece of Ivy Wallet's domain logic is how do we handle transfer with just Income
and Expense
transactions?
The simplest transfer that you can can do, right now, at your home is moving cash from your left pocket to your right one.
If we imagine moving 5$ from the left pocket Account Left
to right one Account Right
, it can be described as:
- Transaction(type=Expense, acc=
Account Left
, value = 5$) - Transation(type=Income, acc=
Account Right
, value = 5$)
However, seeing two separate transactions in your transaction history is weird. Worse both your Income and Expense stats will be increased by $5.
In reality, you didn't spend any money and didn't earn any money. That's why this case must be represented as Transfer
in the UI.
To achieve, Transfers while stil having simple and elegant data model, Ivy Wallet uses "transaction batching". Simply, linking multiple transactions together.
Knowing how Ivy Wallet works under the hood, now let's observe its behavior from user's perspective.
The balance that you see on your home scren is the sum of the balance of all not excluded accounts.
Home Balance =
$\Sigma$ of not excluded account balances
The idea behind that is that you can exlude all non-liquid so that you'll see the money you have at your immediate disposal.
💡 Tip: To see your net worth (total balance with excluded accounts) just click the "Accounts" tab and it'll appear at the top.
Home's Income and expense are calculated by:
- including excluded accounts
- excluding transfer transactions
Formulas:
-
Home Income =
$\Sigma$ incomes from all accounts, excluding transfers -
Home Expense =
$\Sigma$ expenses from all accounts, excluding transfers
Income & Expense for accounts:
-
Account Income =
$\Sigma$ all incomes, including transfers in -
Account Expense =
$\Sigma$ all expenses, including transfers out
-
Category Income =
$\Sigma$ all incomes, excluding transfers -
Category Expense =
$\Sigma$ all expenses, excluding transfers