Compare commits
4 Commits
507d230cca
...
704f25914b
Author | SHA1 | Date |
---|---|---|
Anantha Kumaran | 704f25914b | |
Anantha Kumaran | de0ba74b95 | |
Anantha Kumaran | 26fb7618ef | |
Anantha Kumaran | 8fa191e0d5 |
|
@ -1912,6 +1912,15 @@ let
|
|||
sha512 = "7BUT1sEFSNBIcc0wlwKn2l3l3OnYJdjsrlruDbAp6hpOK3HbpgMjLVH4ql6xXwD+qYy+XEHrb2EMkIpo9kWZ+Q==";
|
||||
};
|
||||
};
|
||||
"@types/tabulator-tables-5.5.7" = {
|
||||
name = "_at_types_slash_tabulator-tables";
|
||||
packageName = "@types/tabulator-tables";
|
||||
version = "5.5.7";
|
||||
src = fetchurl {
|
||||
url = "https://registry.npmjs.org/@types/tabulator-tables/-/tabulator-tables-5.5.7.tgz";
|
||||
sha512 = "2G6i6QhJ/L+8Xk3KAfFZ91qADS9MEu6ve1uT59iaA7fpA6h6AswbFP/5dl3yg8lUhMsP4Zcst073FhbK7Y0TJA==";
|
||||
};
|
||||
};
|
||||
"@types/tar-6.1.10" = {
|
||||
name = "_at_types_slash_tar";
|
||||
packageName = "@types/tar";
|
||||
|
@ -8610,6 +8619,15 @@ let
|
|||
sha512 = "C2PqiSdxDA0v+OH9SP8UxyyfTRLzdxtdwgMjeX/5fvPPYbFixaUXp0hQw3aDN2RrLrwE2vmRJK3sAOICk+0wHA==";
|
||||
};
|
||||
};
|
||||
"tabulator-tables-5.5.4" = {
|
||||
name = "tabulator-tables";
|
||||
packageName = "tabulator-tables";
|
||||
version = "5.5.4";
|
||||
src = fetchurl {
|
||||
url = "https://registry.npmjs.org/tabulator-tables/-/tabulator-tables-5.5.4.tgz";
|
||||
sha512 = "hVcITAfO2G3gm2ILW9GN2ORgcmNsbVmC+Q+2E3xfthIE9xtFxGKSbhbsNk39h11Uzm9GNUvjGfos1IVKrfeeOA==";
|
||||
};
|
||||
};
|
||||
"tailwindcss-3.4.0" = {
|
||||
name = "tailwindcss";
|
||||
packageName = "tailwindcss";
|
||||
|
@ -9762,6 +9780,7 @@ let
|
|||
sources."@types/sprintf-js-1.1.4"
|
||||
sources."@types/svg2ttf-5.0.3"
|
||||
sources."@types/svgicons2svgfont-10.0.5"
|
||||
sources."@types/tabulator-tables-5.5.7"
|
||||
sources."@types/tar-6.1.10"
|
||||
sources."@types/ttf2eot-2.0.2"
|
||||
sources."@types/ttf2woff-2.0.4"
|
||||
|
@ -10731,6 +10750,7 @@ let
|
|||
sources."svgo-3.0.3"
|
||||
sources."svgpath-2.6.0"
|
||||
sources."svgtofont-4.1.1"
|
||||
sources."tabulator-tables-5.5.4"
|
||||
(sources."tailwindcss-3.4.0" // {
|
||||
dependencies = [
|
||||
(sources."postcss-load-config-4.0.2" // {
|
||||
|
|
|
@ -20,7 +20,6 @@ import (
|
|||
type Aggregate struct {
|
||||
Date time.Time `json:"date"`
|
||||
Account string `json:"account"`
|
||||
Amount decimal.Decimal `json:"amount"`
|
||||
MarketAmount decimal.Decimal `json:"market_amount"`
|
||||
}
|
||||
|
||||
|
@ -88,11 +87,9 @@ func computeAggregateTimeline(db *gorm.DB, postings []posting.Posting) []map[str
|
|||
result := make(map[string]Aggregate)
|
||||
|
||||
for account, rsByAccount := range accumulator {
|
||||
amount := decimal.Zero
|
||||
marketAmount := decimal.Zero
|
||||
|
||||
for commodity, rs := range rsByAccount {
|
||||
amount = amount.Add(rs.cost)
|
||||
if utils.IsCurrency(commodity) {
|
||||
marketAmount = marketAmount.Add(rs.cost)
|
||||
} else {
|
||||
|
@ -105,7 +102,7 @@ func computeAggregateTimeline(db *gorm.DB, postings []posting.Posting) []map[str
|
|||
}
|
||||
}
|
||||
|
||||
result[account] = Aggregate{Date: start, Account: account, Amount: amount, MarketAmount: marketAmount}
|
||||
result[account] = Aggregate{Date: start, Account: account, MarketAmount: marketAmount}
|
||||
|
||||
}
|
||||
|
||||
|
@ -151,9 +148,8 @@ func computeAggregate(db *gorm.DB, postings []posting.Posting, date time.Time) m
|
|||
result[parent] = Aggregate{Account: parent}
|
||||
}
|
||||
|
||||
amount := accounting.CostSum(ps)
|
||||
marketAmount := accounting.CurrentBalanceOn(db, ps, date)
|
||||
result[account] = Aggregate{Date: date, Account: account, Amount: amount, MarketAmount: marketAmount}
|
||||
result[account] = Aggregate{Date: date, Account: account, MarketAmount: marketAmount}
|
||||
|
||||
}
|
||||
return result
|
||||
|
|
|
@ -49,6 +49,8 @@ func getRetirementDetail(db *gorm.DB, conf config.RetirementGoal) gin.H {
|
|||
savingsWithCapitalGains := accounting.FilterByGlob(query.Init(db).Like("Assets:%", "Income:CapitalGains:%").All(), conf.Savings)
|
||||
savingsWithCapitalGains = service.PopulateMarketPrice(db, savingsWithCapitalGains)
|
||||
savingsTotal := accounting.CurrentBalance(savings)
|
||||
investmentTotal := accounting.CostBalance(savings)
|
||||
gainsTotal := savingsTotal.Sub(investmentTotal)
|
||||
|
||||
yearlyExpenses := decimal.NewFromFloat(conf.YearlyExpenses)
|
||||
if !(yearlyExpenses.GreaterThan(decimal.Zero)) {
|
||||
|
@ -63,6 +65,8 @@ func getRetirementDetail(db *gorm.DB, conf config.RetirementGoal) gin.H {
|
|||
"icon": conf.Icon,
|
||||
"savingsTimeline": accounting.RunningBalance(db, savings),
|
||||
"savingsTotal": savingsTotal,
|
||||
"investmentTotal": investmentTotal,
|
||||
"gainTotal": gainsTotal,
|
||||
"swr": conf.SWR,
|
||||
"yearlyExpense": yearlyExpenses,
|
||||
"xirr": service.XIRR(db, savingsWithCapitalGains),
|
||||
|
|
|
@ -32,6 +32,7 @@ func getSavingsDetail(db *gorm.DB, conf config.SavingsGoal) gin.H {
|
|||
savings := accounting.FilterByGlob(query.Init(db).Like("Assets:%").All(), conf.Accounts)
|
||||
savings = service.PopulateMarketPrice(db, savings)
|
||||
savingsTotal := accounting.CurrentBalance(savings)
|
||||
investmentTotal := accounting.CostBalance(savings)
|
||||
|
||||
savingsWithCapitalGains := accounting.FilterByGlob(query.Init(db).Like("Assets:%", "Income:CapitalGains:%").All(), conf.Accounts)
|
||||
savingsWithCapitalGains = service.PopulateMarketPrice(db, savingsWithCapitalGains)
|
||||
|
@ -42,8 +43,10 @@ func getSavingsDetail(db *gorm.DB, conf config.SavingsGoal) gin.H {
|
|||
"type": "savings",
|
||||
"name": conf.Name,
|
||||
"icon": conf.Icon,
|
||||
"savingsTimeline": accounting.RunningBalance(db, savings),
|
||||
"investmentTotal": investmentTotal,
|
||||
"savingsTotal": savingsTotal,
|
||||
"gainTotal": savingsTotal.Sub(investmentTotal),
|
||||
"savingsTimeline": accounting.RunningBalance(db, savings),
|
||||
"target": decimal.NewFromFloat(conf.Target),
|
||||
"targetDate": conf.TargetDate,
|
||||
"rate": conf.Rate,
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
"svelte-local-storage-store": "^0.6.0",
|
||||
"svelte-select": "^5.8.0",
|
||||
"svelte-tiny-virtual-list": "^2.0.5",
|
||||
"tabulator-tables": "^5.5.4",
|
||||
"textures": "^1.2.3",
|
||||
"tippy.js": "^6.3.7",
|
||||
"xlsx": "https://cdn.sheetjs.com/xlsx-0.19.3/xlsx-0.19.3.tgz",
|
||||
|
@ -71,6 +72,7 @@
|
|||
"@types/lodash": "^4.14.194",
|
||||
"@types/papaparse": "^5.3.7",
|
||||
"@types/sprintf-js": "^1.1.2",
|
||||
"@types/tabulator-tables": "^5.5.7",
|
||||
"@typescript-eslint/eslint-plugin": "^5.45.0",
|
||||
"@typescript-eslint/parser": "^5.45.0",
|
||||
"autoprefixer": "^10.4.14",
|
||||
|
@ -2639,6 +2641,12 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/tabulator-tables": {
|
||||
"version": "5.5.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/tabulator-tables/-/tabulator-tables-5.5.7.tgz",
|
||||
"integrity": "sha512-2G6i6QhJ/L+8Xk3KAfFZ91qADS9MEu6ve1uT59iaA7fpA6h6AswbFP/5dl3yg8lUhMsP4Zcst073FhbK7Y0TJA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/tar": {
|
||||
"version": "6.1.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/tar/-/tar-6.1.10.tgz",
|
||||
|
@ -11795,6 +11803,11 @@
|
|||
"url": "https://jaywcjlove.github.io/#/sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/tabulator-tables": {
|
||||
"version": "5.5.4",
|
||||
"resolved": "https://registry.npmjs.org/tabulator-tables/-/tabulator-tables-5.5.4.tgz",
|
||||
"integrity": "sha512-hVcITAfO2G3gm2ILW9GN2ORgcmNsbVmC+Q+2E3xfthIE9xtFxGKSbhbsNk39h11Uzm9GNUvjGfos1IVKrfeeOA=="
|
||||
},
|
||||
"node_modules/tailwindcss": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.0.tgz",
|
||||
|
@ -14957,6 +14970,12 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/tabulator-tables": {
|
||||
"version": "5.5.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/tabulator-tables/-/tabulator-tables-5.5.7.tgz",
|
||||
"integrity": "sha512-2G6i6QhJ/L+8Xk3KAfFZ91qADS9MEu6ve1uT59iaA7fpA6h6AswbFP/5dl3yg8lUhMsP4Zcst073FhbK7Y0TJA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/tar": {
|
||||
"version": "6.1.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/tar/-/tar-6.1.10.tgz",
|
||||
|
@ -21796,6 +21815,11 @@
|
|||
"yargs": "~17.7.1"
|
||||
}
|
||||
},
|
||||
"tabulator-tables": {
|
||||
"version": "5.5.4",
|
||||
"resolved": "https://registry.npmjs.org/tabulator-tables/-/tabulator-tables-5.5.4.tgz",
|
||||
"integrity": "sha512-hVcITAfO2G3gm2ILW9GN2ORgcmNsbVmC+Q+2E3xfthIE9xtFxGKSbhbsNk39h11Uzm9GNUvjGfos1IVKrfeeOA=="
|
||||
},
|
||||
"tailwindcss": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.0.tgz",
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
"svelte-local-storage-store": "^0.6.0",
|
||||
"svelte-select": "^5.8.0",
|
||||
"svelte-tiny-virtual-list": "^2.0.5",
|
||||
"tabulator-tables": "^5.5.4",
|
||||
"textures": "^1.2.3",
|
||||
"tippy.js": "^6.3.7",
|
||||
"xlsx": "https://cdn.sheetjs.com/xlsx-0.19.3/xlsx-0.19.3.tgz",
|
||||
|
@ -78,6 +79,7 @@
|
|||
"@types/lodash": "^4.14.194",
|
||||
"@types/papaparse": "^5.3.7",
|
||||
"@types/sprintf-js": "^1.1.2",
|
||||
"@types/tabulator-tables": "^5.5.7",
|
||||
"@typescript-eslint/eslint-plugin": "^5.45.0",
|
||||
"@typescript-eslint/parser": "^5.45.0",
|
||||
"autoprefixer": "^10.4.14",
|
||||
|
|
69
src/app.scss
69
src/app.scss
|
@ -31,6 +31,45 @@ $editor-full-height: calc(100vh - 45.5px - 7px - 15.75px - 21px - 57.75px - 10.5
|
|||
@import "bulma-switch/src/sass/index.sass";
|
||||
@import "@cityssm/bulma-sticky-table/sticky-table";
|
||||
|
||||
$backgroundColor: $white;
|
||||
$borderColor: none;
|
||||
$textSize: 1rem;
|
||||
$headerBackgroundColor: $white;
|
||||
$headerTextColor: $grey-dark;
|
||||
$headerBorderColor: rgba($grey-lightest, 1);
|
||||
$headerSeparatorColor: rgba($grey-light, 0.5);
|
||||
$headerMargin: 0.2857rem;
|
||||
$sortArrowActive: $black;
|
||||
$sortArrowInactive: $grey-light;
|
||||
$rowBackgroundColor: $white;
|
||||
$rowAltBackgroundColor: $white;
|
||||
$rowBorderColor: rgba($grey-lightest, 0.5);
|
||||
$rowTextColor: $grey-dark;
|
||||
$rowHoverBackground: $white-bis;
|
||||
$rowSelectedBackground: #9abcea;
|
||||
$rowSelectedBackgroundHover: #769bcc;
|
||||
$editBoxColor: #1d68cd;
|
||||
$errorColor: #dd0000;
|
||||
$footerBackgroundColor: #fff;
|
||||
$footerTextColor: #555;
|
||||
$footerBorderColor: #aaa;
|
||||
$footerSeparatorColor: #999;
|
||||
$footerActiveColor: #d00;
|
||||
|
||||
@import "tabulator-tables/src/scss/themes/tabulator_simple.scss";
|
||||
|
||||
.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.tabulator {
|
||||
border-radius: $radius;
|
||||
}
|
||||
|
||||
.tabulator-col {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
// override message style
|
||||
|
||||
.message {
|
||||
|
@ -111,7 +150,7 @@ $editor-full-height: calc(100vh - 45.5px - 7px - 15.75px - 21px - 57.75px - 10.5
|
|||
}
|
||||
|
||||
.du-range {
|
||||
--range-shdw: var(--nc);
|
||||
--range-shdw: var(--fallback-bc, oklch(var(--nc) / 1));
|
||||
}
|
||||
|
||||
.modal-background {
|
||||
|
@ -441,7 +480,13 @@ svg text {
|
|||
}
|
||||
|
||||
.weekdays-grid {
|
||||
border-radius: $radius-small;
|
||||
div:first-child {
|
||||
border-radius: $radius-small 0 0 $radius-small !important;
|
||||
}
|
||||
|
||||
div:last-child {
|
||||
border-radius: 0 $radius-small $radius-small 0 !important;
|
||||
}
|
||||
|
||||
div {
|
||||
padding: 2px 0;
|
||||
|
@ -525,10 +570,13 @@ nav.level.grid-2 {
|
|||
}
|
||||
|
||||
.navbar {
|
||||
background-color: $white-bis !important;
|
||||
background-color: $white !important;
|
||||
color: rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
|
||||
a.navbar-item {
|
||||
background-color: $white !important;
|
||||
}
|
||||
}
|
||||
.cm-editor {
|
||||
.cm-gutters {
|
||||
background-color: $white-ter;
|
||||
|
@ -1044,6 +1092,19 @@ textarea:invalid {
|
|||
border-color: $danger;
|
||||
}
|
||||
|
||||
.dropdown-trigger.dropdown-icon {
|
||||
button {
|
||||
height: 2rem;
|
||||
padding: 0;
|
||||
border: none;
|
||||
background: none;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
color: $link;
|
||||
}
|
||||
}
|
||||
|
||||
.nested.has-dropdown {
|
||||
&:hover > .dropdown-menu {
|
||||
display: block;
|
||||
|
|
|
@ -280,7 +280,7 @@ function renderPartition(
|
|||
.attr("data-tippy-content", (d) => {
|
||||
return tooltip([
|
||||
["Account", [d.id, "has-text-right"]],
|
||||
["MarketAmount", [formatCurrency(d.value), "has-text-weight-bold has-text-right"]],
|
||||
["Market Value", [formatCurrency(d.value), "has-text-weight-bold has-text-right"]],
|
||||
["Percentage", [percent(d), "has-text-weight-bold has-text-right"]]
|
||||
]);
|
||||
})
|
||||
|
@ -309,13 +309,12 @@ export function renderAllocationTimeline(
|
|||
const timeline = _.map(aggregatesTimeline, (aggregates) => {
|
||||
return _.chain(aggregates)
|
||||
.values()
|
||||
.filter((a) => a.amount != 0)
|
||||
.filter((a) => a.market_amount != 0)
|
||||
.groupBy((a) => secondName(a.account))
|
||||
.map((aggregates, group) => {
|
||||
return {
|
||||
date: aggregates[0].date,
|
||||
account: group,
|
||||
amount: _.sum(_.map(aggregates, (a) => a.amount)),
|
||||
market_amount: _.sum(_.map(aggregates, (a) => a.market_amount)),
|
||||
timestamp: aggregates[0].date
|
||||
};
|
||||
|
|
|
@ -5,14 +5,10 @@
|
|||
import { obscure } from "../../persisted_store";
|
||||
import { goto } from "$app/navigation";
|
||||
|
||||
let isLoading = false;
|
||||
|
||||
async function syncWithLoader(request: Record<string, any>) {
|
||||
isLoading = true;
|
||||
try {
|
||||
await sync(request);
|
||||
} finally {
|
||||
isLoading = false;
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
@ -33,11 +29,11 @@
|
|||
let showLogout = isLoggedIn();
|
||||
</script>
|
||||
|
||||
<div class="dropdown {isMobile() ? 'is-left' : 'is-right'}" class:is-hoverable={!isLoading}>
|
||||
<div class="dropdown-trigger">
|
||||
<button class:is-loading={isLoading} class="button is-small" aria-haspopup="true">
|
||||
<span class="icon is-small">
|
||||
<i class="fas fa-caret-down" />
|
||||
<div class="dropdown ml-2 is-hoverable {isMobile() ? 'is-left' : 'is-right'}">
|
||||
<div class="dropdown-trigger dropdown-icon">
|
||||
<button class="button is-large" aria-haspopup="true">
|
||||
<span class="icon">
|
||||
<i class="fas fa-ellipsis-vertical" />
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -1,75 +1,65 @@
|
|||
<script lang="ts">
|
||||
import { iconText } from "$lib/icon";
|
||||
import {
|
||||
type AssetBreakdown,
|
||||
depth,
|
||||
lastName,
|
||||
isZero,
|
||||
formatCurrency,
|
||||
formatFloat,
|
||||
formatPercentage
|
||||
} from "$lib/utils";
|
||||
import { type AssetBreakdown, buildTree } from "$lib/utils";
|
||||
import _ from "lodash";
|
||||
import Table from "./Table.svelte";
|
||||
import type { ColumnDefinition } from "tabulator-tables";
|
||||
import {
|
||||
accountName,
|
||||
formatCurrencyChange,
|
||||
indendedAssetAccountName,
|
||||
nonZeroCurrency,
|
||||
nonZeroFloatChange,
|
||||
nonZeroPercentageChange
|
||||
} from "$lib/table_formatters";
|
||||
|
||||
export let breakdowns: Record<string, AssetBreakdown>;
|
||||
export let indent = true;
|
||||
|
||||
function calculateChangeClass(gain: number) {
|
||||
let changeClass = "";
|
||||
if (gain > 0) {
|
||||
changeClass = "has-text-success";
|
||||
} else if (gain < 0) {
|
||||
changeClass = "has-text-danger";
|
||||
const columns: ColumnDefinition[] = [
|
||||
{
|
||||
title: "Account",
|
||||
field: "group",
|
||||
formatter: indent ? indendedAssetAccountName : accountName,
|
||||
frozen: true
|
||||
},
|
||||
{
|
||||
title: "Investment Amount",
|
||||
field: "investmentAmount",
|
||||
hozAlign: "right",
|
||||
vertAlign: "middle",
|
||||
formatter: nonZeroCurrency
|
||||
},
|
||||
{
|
||||
title: "Withdrawal Amount",
|
||||
field: "withdrawalAmount",
|
||||
hozAlign: "right",
|
||||
formatter: nonZeroCurrency
|
||||
},
|
||||
{
|
||||
title: "Balance Units",
|
||||
field: "balanceUnits",
|
||||
hozAlign: "right",
|
||||
formatter: nonZeroCurrency
|
||||
},
|
||||
{ title: "Market Value", field: "marketAmount", hozAlign: "right", formatter: nonZeroCurrency },
|
||||
{ title: "Change", field: "gainAmount", hozAlign: "right", formatter: formatCurrencyChange },
|
||||
{ title: "XIRR", field: "xirr", hozAlign: "right", formatter: nonZeroFloatChange },
|
||||
{
|
||||
title: "Absolute Return",
|
||||
field: "absoluteReturn",
|
||||
hozAlign: "right",
|
||||
formatter: nonZeroPercentageChange
|
||||
}
|
||||
return changeClass;
|
||||
];
|
||||
|
||||
let tree: AssetBreakdown[] = [];
|
||||
$: if (breakdowns) {
|
||||
tree = buildTree(Object.values(breakdowns), (i) => i.group);
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="box overflow-x-auto max-h-screen max-w-fit pt-0">
|
||||
<table class="table is-narrow is-hoverable is-light-border has-sticky-header">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="py-2">Account</th>
|
||||
<th class="py-2 has-text-right">Investment Amount</th>
|
||||
<th class="py-2 has-text-right">Withdrawal Amount</th>
|
||||
<th class="py-2 has-text-right">Balance Units</th>
|
||||
<th class="py-2 has-text-right">Market Value</th>
|
||||
<th class="py-2 has-text-right">Change</th>
|
||||
<th class="py-2 has-text-right">XIRR</th>
|
||||
<th class="py-2 has-text-right">Absolute Return</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="has-text-grey-dark">
|
||||
{#each Object.values(breakdowns) as b}
|
||||
{@const indentWidth = indent ? _.repeat("  ", depth(b.group) - 1) : ""}
|
||||
{@const gain = b.gainAmount}
|
||||
{@const changeClass = calculateChangeClass(gain)}
|
||||
<tr>
|
||||
<td
|
||||
class="whitespace-nowrap has-text-left"
|
||||
style="max-width: max(15rem, 33.33vw); overflow: hidden;"
|
||||
>{@html indentWidth}<span class="has-text-grey custom-icon">{iconText(b.group)}</span>
|
||||
<a href="/assets/gain/{b.group}">{indent ? lastName(b.group) : b.group}</a></td
|
||||
>
|
||||
<td class="has-text-right"
|
||||
>{!isZero(b.investmentAmount) ? formatCurrency(b.investmentAmount) : ""}</td
|
||||
>
|
||||
<td class="has-text-right"
|
||||
>{!isZero(b.withdrawalAmount) ? formatCurrency(b.withdrawalAmount) : ""}</td
|
||||
>
|
||||
<td class="has-text-right">{b.balanceUnits > 0 ? formatFloat(b.balanceUnits, 4) : ""}</td>
|
||||
<td class="has-text-right"
|
||||
>{!isZero(b.marketAmount) ? formatCurrency(b.marketAmount) : ""}</td
|
||||
>
|
||||
<td class="{changeClass} has-text-right"
|
||||
>{!isZero(b.investmentAmount) && !isZero(gain) ? formatCurrency(gain) : ""}</td
|
||||
>
|
||||
<td class="{changeClass} has-text-right">{!isZero(b.xirr) ? formatFloat(b.xirr) : ""}</td>
|
||||
<td class="{changeClass} has-text-right"
|
||||
>{!isZero(b.absoluteReturn) ? formatPercentage(b.absoluteReturn, 2) : ""}</td
|
||||
>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{#if indent}
|
||||
<Table data={tree} tree {columns} />
|
||||
{:else}
|
||||
<Table data={Object.values(breakdowns)} {columns} />
|
||||
{/if}
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
href="/liabilities/credit_cards/{encodeURIComponent(creditCard.account)}"
|
||||
>
|
||||
<span class="custom-icon">{iconText(creditCard.account)}</span>
|
||||
<span class="ml-1">{restName(restName(creditCard.account))}</span>
|
||||
<span>{restName(restName(creditCard.account))}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
{small}
|
||||
narrow
|
||||
title="Target"
|
||||
color={COLORS.secondary}
|
||||
color={COLORS.primary}
|
||||
value={formatCurrency(goal.target)}
|
||||
/>
|
||||
</nav>
|
||||
|
|
|
@ -118,7 +118,7 @@
|
|||
label: "More",
|
||||
href: "/more",
|
||||
children: [
|
||||
{ label: "Configuration", href: "/config", tag: "alpha", help: "config" },
|
||||
{ label: "Configuration", href: "/config", help: "config" },
|
||||
{ label: "Sheets", href: "/sheets", help: "sheets", disablePreload: true },
|
||||
{ label: "Goals", href: "/goals", help: "goals" },
|
||||
{ label: "Doctor", href: "/doctor" },
|
||||
|
@ -310,7 +310,7 @@
|
|||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="mt-2 px-3 is-flex is-justify-content-space-between">
|
||||
<div class="mt-3 px-3 is-flex is-justify-content-space-between">
|
||||
{#if selectedLink}
|
||||
<nav
|
||||
style="margin-left: 0.73rem;"
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
<script lang="ts">
|
||||
import { rem } from "$lib/utils";
|
||||
import { onMount } from "svelte";
|
||||
import { TabulatorFull as Tabulator, type ColumnDefinition } from "tabulator-tables";
|
||||
|
||||
export let data: any[];
|
||||
export let columns: ColumnDefinition[];
|
||||
export let tree = false;
|
||||
|
||||
let tableComponent: HTMLElement;
|
||||
let tabulator: Tabulator;
|
||||
|
||||
$: if (data.length > 0) {
|
||||
build();
|
||||
}
|
||||
|
||||
async function build() {
|
||||
if (data.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (tabulator) {
|
||||
tabulator.replaceData(data);
|
||||
} else {
|
||||
tabulator = new Tabulator(tableComponent, {
|
||||
dataTree: tree,
|
||||
dataTreeStartExpanded: [true, true, false],
|
||||
dataTreeBranchElement: false,
|
||||
dataTreeChildIndent: rem(30),
|
||||
dataTreeCollapseElement:
|
||||
"<span class='has-text-link icon is-small mr-3'><i class='fas fa-angle-up'></i></span>",
|
||||
dataTreeExpandElement:
|
||||
"<span class='has-text-link icon is-small mr-3'><i class='fas fa-angle-down'></i></span>",
|
||||
data: data,
|
||||
columns: columns,
|
||||
maxHeight: "100vh",
|
||||
layout: "fitDataTable"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
build();
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="overflow-x-auto box py-0" style="max-width: 100%;" bind:this={tableComponent}></div>
|
|
@ -180,7 +180,7 @@ export function renderProgress(
|
|||
const lineScale = d3
|
||||
.scaleOrdinal<string>()
|
||||
.domain(lineKeys)
|
||||
.range([COLORS.gainText, COLORS.secondary]);
|
||||
.range([COLORS.secondary, COLORS.primary]);
|
||||
|
||||
const x = d3.scaleTime().range([0, width]).domain([start, end]),
|
||||
y = d3
|
||||
|
@ -391,7 +391,7 @@ export function renderInvestmentTimeline(postings: Posting[], element: Element,
|
|||
if (pmt > 0) {
|
||||
g.append("line")
|
||||
.attr("fill", "none")
|
||||
.attr("stroke", COLORS.secondary)
|
||||
.attr("stroke", COLORS.primary)
|
||||
.attr("x1", 0)
|
||||
.attr("x2", width)
|
||||
.attr("y1", y(pmt))
|
||||
|
@ -406,7 +406,7 @@ export function renderInvestmentTimeline(postings: Posting[], element: Element,
|
|||
.attr("dy", "0.3em")
|
||||
.attr("x", width)
|
||||
.attr("y", y(pmt))
|
||||
.attr("fill", COLORS.secondary)
|
||||
.attr("fill", COLORS.primary)
|
||||
.text(formatCurrencyCrude(pmt));
|
||||
}
|
||||
|
||||
|
@ -415,9 +415,9 @@ export function renderInvestmentTimeline(postings: Posting[], element: Element,
|
|||
.data(points)
|
||||
.enter()
|
||||
.append("rect")
|
||||
.attr("stroke", (p) => (p.total <= 0 ? COLORS.lossText : COLORS.gainText))
|
||||
.attr("fill", (p) => (p.total <= 0 ? COLORS.lossText : COLORS.gainText))
|
||||
.attr("fill-opacity", 0.6)
|
||||
.attr("stroke", (p) => (p.total <= 0 ? COLORS.tertiary : COLORS.secondary))
|
||||
.attr("fill", (p) => (p.total <= 0 ? COLORS.tertiary : COLORS.secondary))
|
||||
.attr("fill-opacity", 0.5)
|
||||
.attr("data-tippy-content", (p) => {
|
||||
const group = groupSumBy(p.postings, (p) => p.account);
|
||||
return tooltip(
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
import { type CellComponent } from "tabulator-tables";
|
||||
import { formatCurrency, formatFloat, formatPercentage, isZero, lastName } from "./utils";
|
||||
import { iconText } from "./icon";
|
||||
|
||||
export function indendedAssetAccountName(cell: CellComponent) {
|
||||
const account = cell.getValue();
|
||||
let children = "";
|
||||
const data = cell.getData();
|
||||
if ((data._children?.length || 0) > 0) {
|
||||
children = `(${data._children?.length})`;
|
||||
}
|
||||
return `
|
||||
<span class="whitespace-nowrap" style="max-width: max(15rem, 33.33vw); overflow: hidden;">
|
||||
<span class="has-text-grey custom-icon">${iconText(account)}</span>
|
||||
<a href="/assets/gain/${account}">${lastName(account)}</a>
|
||||
<span class="has-text-grey-light is-size-7">${children}</span>
|
||||
</span>
|
||||
`;
|
||||
}
|
||||
|
||||
export function indendedLiabilityAccountName(cell: CellComponent) {
|
||||
const account = cell.getValue();
|
||||
let children = "";
|
||||
const data = cell.getData();
|
||||
if ((data._children?.length || 0) > 0) {
|
||||
children = `(${data._children?.length})`;
|
||||
}
|
||||
return `
|
||||
<span class="whitespace-nowrap" style="max-width: max(15rem, 33.33vw); overflow: hidden;">
|
||||
<span class="has-text-grey custom-icon">${iconText(account)}</span>
|
||||
<span>${lastName(account)}</span>
|
||||
<span class="has-text-grey-light is-size-7">${children}</span>
|
||||
</span>
|
||||
`;
|
||||
}
|
||||
|
||||
export function accountName(cell: CellComponent) {
|
||||
const account = cell.getValue();
|
||||
return `
|
||||
<span class="whitespace-nowrap" style="max-width: max(15rem, 33.33vw); overflow: hidden;">
|
||||
<span class="has-text-grey custom-icon">${iconText(account)}</span>
|
||||
<a href="/assets/gain/${account}">${account}</a>
|
||||
</span>
|
||||
`;
|
||||
}
|
||||
|
||||
function calculateChangeClass(gain: number) {
|
||||
let changeClass = "";
|
||||
if (gain > 0) {
|
||||
changeClass = "has-text-success";
|
||||
} else if (gain < 0) {
|
||||
changeClass = "has-text-danger";
|
||||
}
|
||||
return changeClass;
|
||||
}
|
||||
|
||||
export function nonZeroCurrency(cell: CellComponent) {
|
||||
const value = cell.getValue();
|
||||
return isZero(value) ? "" : formatCurrency(value);
|
||||
}
|
||||
|
||||
export function nonZeroFloatChange(cell: CellComponent) {
|
||||
const value = cell.getValue();
|
||||
return isZero(value)
|
||||
? ""
|
||||
: `<span class="${calculateChangeClass(value)}">${formatFloat(value)}</span>`;
|
||||
}
|
||||
|
||||
export function nonZeroPercentageChange(cell: CellComponent) {
|
||||
const value = cell.getValue();
|
||||
return isZero(value)
|
||||
? ""
|
||||
: `<span class="${calculateChangeClass(value)}">${formatPercentage(value, 2)}</span>`;
|
||||
}
|
||||
|
||||
export function formatCurrencyChange(cell: CellComponent) {
|
||||
const value = cell.getValue();
|
||||
return isZero(value)
|
||||
? ""
|
||||
: `<span class="${calculateChangeClass(value)}">${formatCurrency(value)}</span>`;
|
||||
}
|
|
@ -183,8 +183,10 @@ export interface LiabilityBreakdown {
|
|||
export interface Aggregate {
|
||||
date: dayjs.Dayjs;
|
||||
account: string;
|
||||
amount: number;
|
||||
market_amount: number;
|
||||
|
||||
// computed
|
||||
percent: number;
|
||||
}
|
||||
|
||||
export interface CommodityBreakdown {
|
||||
|
@ -356,6 +358,8 @@ export interface AccountBudget {
|
|||
|
||||
export interface RetirementGoalProgress {
|
||||
savingsTotal: number;
|
||||
investmentTotal: number;
|
||||
gainTotal: number;
|
||||
savingsTimeline: Point[];
|
||||
swr: number;
|
||||
yearlyExpense: number;
|
||||
|
@ -368,6 +372,8 @@ export interface RetirementGoalProgress {
|
|||
}
|
||||
|
||||
export interface SavingsGoalProgress {
|
||||
investmentTotal: number;
|
||||
gainTotal: number;
|
||||
savingsTotal: number;
|
||||
savingsTimeline: Point[];
|
||||
target: number;
|
||||
|
@ -1272,3 +1278,30 @@ export function dueDateIcon(dueDate: dayjs.Dayjs, clearedDate: dayjs.Dayjs) {
|
|||
|
||||
return { icon, color, svgColor, glyph };
|
||||
}
|
||||
|
||||
export function buildTree<I>(items: I[], accountAccessor: (item: I) => string): I[] {
|
||||
const result: I[] = [];
|
||||
|
||||
const sorted = _.sortBy(items, accountAccessor);
|
||||
|
||||
for (const item of sorted) {
|
||||
const account = accountAccessor(item);
|
||||
const parts = account.split(":");
|
||||
let current = result;
|
||||
for (let i = 0; i < parts.length; i++) {
|
||||
const part = parts[i];
|
||||
let found: any = current.find((c) => accountAccessor(c).split(":")[i] === part);
|
||||
if (!found) {
|
||||
found = { ...item };
|
||||
current.push(found);
|
||||
}
|
||||
|
||||
if (i !== parts.length - 1) {
|
||||
found._children = found._children || [];
|
||||
current = found._children;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -228,7 +228,7 @@
|
|||
<strong>Oops!</strong> You have not made any transactions in the last 3 months.
|
||||
</ZeroState>
|
||||
|
||||
<LegendCard legends={cashflowLegends} clazz="mb-2 overflow-x-scroll" />
|
||||
<LegendCard legends={cashflowLegends} clazz="mb-2 overflow-x-auto" />
|
||||
|
||||
<svg
|
||||
class:is-not-visible={_.isEmpty(cashFlows)}
|
||||
|
|
|
@ -4,16 +4,49 @@
|
|||
renderAllocationTarget,
|
||||
renderAllocationTimeline
|
||||
} from "$lib/allocation";
|
||||
import { generateColorScheme } from "$lib/colors";
|
||||
import COLORS, { generateColorScheme } from "$lib/colors";
|
||||
import BoxLabel from "$lib/components/BoxLabel.svelte";
|
||||
import LegendCard from "$lib/components/LegendCard.svelte";
|
||||
import { ajax, type Legend } from "$lib/utils";
|
||||
import Table from "$lib/components/Table.svelte";
|
||||
import { accountName, nonZeroCurrency } from "$lib/table_formatters";
|
||||
import { ajax, formatPercentage, rem, type Aggregate, type Legend } from "$lib/utils";
|
||||
import _ from "lodash";
|
||||
import { onMount, tick } from "svelte";
|
||||
import type { ColumnDefinition, ProgressBarParams } from "tabulator-tables";
|
||||
|
||||
let showAllocation = false;
|
||||
let depth = 2;
|
||||
let allocationTimelineLegends: Legend[] = [];
|
||||
let aggregateLeafNodes: Aggregate[] = [];
|
||||
let total = 0;
|
||||
|
||||
const columns: ColumnDefinition[] = [
|
||||
{ title: "Account", field: "account", formatter: accountName },
|
||||
{
|
||||
title: "Market Value",
|
||||
field: "market_amount",
|
||||
hozAlign: "right",
|
||||
formatter: nonZeroCurrency
|
||||
},
|
||||
{
|
||||
title: "Percent",
|
||||
field: "percent",
|
||||
hozAlign: "right",
|
||||
formatter: (cell) => formatPercentage(cell.getValue() / 100, 2)
|
||||
},
|
||||
{
|
||||
title: "%",
|
||||
field: "percent",
|
||||
hozAlign: "right",
|
||||
formatter: "progress",
|
||||
cssClass: "has-text-left",
|
||||
minWidth: rem(250),
|
||||
formatterParams: {
|
||||
color: COLORS.assets,
|
||||
min: 0
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
onMount(async () => {
|
||||
const {
|
||||
|
@ -22,6 +55,14 @@
|
|||
allocation_targets: allocationTargets
|
||||
} = await ajax("/api/allocation");
|
||||
const accounts = _.keys(aggregates);
|
||||
aggregateLeafNodes = _.filter(_.values(aggregates), (a) => a.market_amount > 0);
|
||||
total = _.sumBy(aggregateLeafNodes, (a) => a.market_amount);
|
||||
aggregateLeafNodes = _.map(aggregateLeafNodes, (a) => {
|
||||
a.percent = (a.market_amount / total) * 100;
|
||||
return a;
|
||||
});
|
||||
const max = _.max(_.map(aggregateLeafNodes, (a) => a.percent)) || 100;
|
||||
(_.last(columns).formatterParams as ProgressBarParams).max = max;
|
||||
const color = generateColorScheme(accounts);
|
||||
depth = _.max(_.map(accounts, (account) => account.split(":").length));
|
||||
|
||||
|
@ -82,3 +123,13 @@
|
|||
<BoxLabel text="Allocation Timeline" />
|
||||
</div>
|
||||
</section>
|
||||
<section class="section tab-allocation">
|
||||
<div class="container is-fluid">
|
||||
<div class="columns">
|
||||
<div class="column is-12">
|
||||
<Table data={aggregateLeafNodes} tree {columns} />
|
||||
</div>
|
||||
</div>
|
||||
<BoxLabel text="Allocation Table" />
|
||||
</div>
|
||||
</section>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import { onMount } from "svelte";
|
||||
import _ from "lodash";
|
||||
import { renderFlow } from "$lib/cash_flow";
|
||||
import { ajax, depth, firstName, type Graph, type Legend, type Posting } from "$lib/utils";
|
||||
import { ajax, depth, firstName, rem, type Graph, type Legend, type Posting } from "$lib/utils";
|
||||
import { dateMin, year } from "../../../../store";
|
||||
import {
|
||||
setCashflowDepthAllowed,
|
||||
|
@ -69,7 +69,7 @@
|
|||
});
|
||||
</script>
|
||||
|
||||
<section class="section">
|
||||
<section class="section" style="padding-bottom: 0 !important">
|
||||
<div class="container is-fluid">
|
||||
<div class="columns">
|
||||
<div class="column is-12">
|
||||
|
@ -82,7 +82,7 @@
|
|||
<svg
|
||||
class:is-not-visible={isEmpty}
|
||||
id="d3-expense-flow"
|
||||
height={window.innerHeight - 100}
|
||||
height={window.innerHeight - rem(210)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -196,7 +196,7 @@
|
|||
<ZeroState item={expenses}>
|
||||
<strong>Oops!</strong> You have no expenses.
|
||||
</ZeroState>
|
||||
<LegendCard {legends} clazz="ml-4" />
|
||||
<LegendCard {legends} clazz="ml-4 overflow-x-auto" />
|
||||
<svg id="d3-monthly-expense-timeline" width="100%" height="400" />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -246,7 +246,7 @@
|
|||
<div class="container is-fluid">
|
||||
<div class="columns mb-0">
|
||||
<div class="column is-5 py-0">
|
||||
<div class="box p-3 mb-3 overflow-x-scroll">
|
||||
<div class="box p-3 mb-3 overflow-x-auto">
|
||||
<div class="field is-grouped mb-0">
|
||||
<p class="control">
|
||||
<span data-tippy-content="Create" data-tippy-followCursor="false">
|
||||
|
@ -426,14 +426,14 @@
|
|||
float: right;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
z-index: 10;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.save {
|
||||
float: right;
|
||||
position: absolute !important;
|
||||
right: 40px;
|
||||
z-index: 10;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.table-wrapper {
|
||||
|
|
|
@ -1,29 +1,18 @@
|
|||
<script lang="ts">
|
||||
import { iconText } from "$lib/icon";
|
||||
import Table from "$lib/components/Table.svelte";
|
||||
import {
|
||||
ajax,
|
||||
depth,
|
||||
formatCurrency,
|
||||
formatFloat,
|
||||
lastName,
|
||||
type LiabilityBreakdown
|
||||
} from "$lib/utils";
|
||||
indendedLiabilityAccountName,
|
||||
nonZeroCurrency,
|
||||
nonZeroFloatChange
|
||||
} from "$lib/table_formatters";
|
||||
import { ajax, buildTree, type LiabilityBreakdown } from "$lib/utils";
|
||||
import _ from "lodash";
|
||||
import { onMount } from "svelte";
|
||||
import type { ColumnDefinition } from "tabulator-tables";
|
||||
|
||||
let breakdowns: LiabilityBreakdown[] = [];
|
||||
let isEmpty = false;
|
||||
|
||||
function calculateChangeClass(gain: number) {
|
||||
let changeClass = "";
|
||||
if (gain > 0) {
|
||||
changeClass = "has-text-success";
|
||||
} else if (gain < 0) {
|
||||
changeClass = "has-text-danger";
|
||||
}
|
||||
return changeClass;
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
({ liability_breakdowns: breakdowns } = await ajax("/api/liabilities/balance"));
|
||||
|
||||
|
@ -31,6 +20,46 @@
|
|||
isEmpty = true;
|
||||
}
|
||||
});
|
||||
|
||||
const columns: ColumnDefinition[] = [
|
||||
{
|
||||
title: "Account",
|
||||
field: "group",
|
||||
formatter: indendedLiabilityAccountName,
|
||||
frozen: true
|
||||
},
|
||||
{
|
||||
title: "Drawn Amount",
|
||||
field: "drawn_amount",
|
||||
hozAlign: "right",
|
||||
vertAlign: "middle",
|
||||
formatter: nonZeroCurrency
|
||||
},
|
||||
{
|
||||
title: "Repaid Amount",
|
||||
field: "repaid_amount",
|
||||
hozAlign: "right",
|
||||
formatter: nonZeroCurrency
|
||||
},
|
||||
{
|
||||
title: "Balance Amount",
|
||||
field: "balance_amount",
|
||||
hozAlign: "right",
|
||||
formatter: nonZeroCurrency
|
||||
},
|
||||
{
|
||||
title: "Interest",
|
||||
field: "interest_amount",
|
||||
hozAlign: "right",
|
||||
formatter: nonZeroCurrency
|
||||
},
|
||||
{ title: "APR", field: "apr", hozAlign: "right", formatter: nonZeroFloatChange }
|
||||
];
|
||||
|
||||
let tree: LiabilityBreakdown[] = [];
|
||||
$: if (breakdowns) {
|
||||
tree = buildTree(Object.values(breakdowns), (i) => i.group);
|
||||
}
|
||||
</script>
|
||||
|
||||
<section class="section" class:is-hidden={!isEmpty}>
|
||||
|
@ -51,48 +80,7 @@
|
|||
<div class="container is-fluid">
|
||||
<div class="columns">
|
||||
<div class="column is-12 pb-0">
|
||||
<div class="box overflow-x-auto max-h-screen max-w-fit pt-0">
|
||||
<table class="table is-narrow is-hoverable has-sticky-header is-light-border">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="py-2">Account</th>
|
||||
<th class="py-2 has-text-right">Drawn Amount</th>
|
||||
<th class="py-2 has-text-right">Repaid Amount</th>
|
||||
<th class="py-2 has-text-right">Balance Amount</th>
|
||||
<th class="py-2 has-text-right">Interest</th>
|
||||
<th class="py-2 has-text-right">APR</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="has-text-grey-dark">
|
||||
{#each Object.values(breakdowns) as b}
|
||||
{@const indent = _.repeat("  ", depth(b.group) - 1)}
|
||||
{@const changeClass = calculateChangeClass(-b.interest_amount)}
|
||||
<tr>
|
||||
<td class="whitespace-nowrap" style="max-width: 200px; overflow: hidden;"
|
||||
>{@html indent}<span class="has-text-grey custom-icon">{iconText(b.group)}</span
|
||||
>
|
||||
{lastName(b.group)}</td
|
||||
>
|
||||
<td class="has-text-right"
|
||||
>{b.drawn_amount != 0 ? formatCurrency(b.drawn_amount) : ""}</td
|
||||
>
|
||||
<td class="has-text-right"
|
||||
>{b.repaid_amount != 0 ? formatCurrency(b.repaid_amount) : ""}</td
|
||||
>
|
||||
<td class="has-text-right"
|
||||
>{b.balance_amount != 0 ? formatCurrency(b.balance_amount) : ""}</td
|
||||
>
|
||||
<td class="has-text-right"
|
||||
>{b.interest_amount != 0 ? formatCurrency(b.interest_amount) : ""}</td
|
||||
>
|
||||
<td class="{changeClass} has-text-right"
|
||||
>{b.apr > 0.0001 || b.apr < -0.0001 ? formatFloat(b.apr) : ""}</td
|
||||
>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<Table data={tree} tree {columns} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -105,7 +105,7 @@
|
|||
{#if currentBill}
|
||||
<div class="flex flex-wrap gap-4 mb-4">
|
||||
<div
|
||||
class="box py-2 m-0 flex-grow overflow-x-scroll"
|
||||
class="box py-2 m-0 flex-grow overflow-x-auto"
|
||||
style="border: 1px solid transparent"
|
||||
>
|
||||
<div class="is-flex mr-2 is-align-items-baseline" style="min-width: fit-content">
|
||||
|
@ -134,7 +134,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<nav class="level flex gap-4 overflow-x-scroll" style="justify-content: start;">
|
||||
<nav class="level flex gap-4 overflow-x-auto" style="justify-content: start;">
|
||||
<LevelItem
|
||||
{small}
|
||||
narrow
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
let svg: Element;
|
||||
let investmentTimelineSvg: Element;
|
||||
let savingsTotal = 0,
|
||||
investmentTotal = 0,
|
||||
gainTotal = 0,
|
||||
icon = "",
|
||||
name = "",
|
||||
targetSavings = 0,
|
||||
|
@ -48,8 +50,19 @@
|
|||
});
|
||||
|
||||
onMount(async () => {
|
||||
({ savingsTotal, savingsTimeline, yearlyExpense, swr, xirr, icon, name, postings, balances } =
|
||||
await ajax("/api/goals/retirement/:name", null, data));
|
||||
({
|
||||
savingsTotal,
|
||||
investmentTotal,
|
||||
gainTotal,
|
||||
savingsTimeline,
|
||||
yearlyExpense,
|
||||
swr,
|
||||
xirr,
|
||||
icon,
|
||||
name,
|
||||
postings,
|
||||
balances
|
||||
} = await ajax("/api/goals/retirement/:name", null, data));
|
||||
targetSavings = yearlyExpense * (100 / swr);
|
||||
|
||||
latestPostings = _.chain(postings)
|
||||
|
@ -84,6 +97,15 @@
|
|||
<div class="container is-fluid">
|
||||
<nav class="level custom-icon {isMobile() && 'grid-2'}">
|
||||
<LevelItem title={name} value={iconGlyph(icon)} />
|
||||
<LevelItem
|
||||
title="Net Investment"
|
||||
value={formatCurrency(investmentTotal)}
|
||||
color={COLORS.secondary}
|
||||
subtitle={`<b>${formatCurrency(gainTotal)}</b> ${
|
||||
gainTotal >= 0 ? "gain" : "loss"
|
||||
} at <b>${formatFloat(xirr)}</b> XIRR`}
|
||||
/>
|
||||
|
||||
<LevelItem
|
||||
title="Current Savings"
|
||||
value={formatCurrency(savingsTotal)}
|
||||
|
@ -99,11 +121,10 @@
|
|||
<LevelItem
|
||||
title="Target Savings"
|
||||
value={formatCurrency(targetSavings)}
|
||||
color={COLORS.secondary}
|
||||
color={COLORS.primary}
|
||||
subtitle="{formatFloat(targetX, 0)}x times Yearly Expenses"
|
||||
/>
|
||||
<LevelItem title="SWR" value={formatFloat(swr)} />
|
||||
<LevelItem title="XIRR" value={formatFloat(xirr)} />
|
||||
</nav>
|
||||
</div>
|
||||
</section>
|
||||
|
@ -149,11 +170,11 @@
|
|||
{posting}
|
||||
color={posting.amount >= 0
|
||||
? posting.account.startsWith("Income:CapitalGains")
|
||||
? COLORS.lossText
|
||||
: COLORS.gainText
|
||||
? COLORS.tertiary
|
||||
: COLORS.secondary
|
||||
: posting.account.startsWith("Income:CapitalGains")
|
||||
? COLORS.gainText
|
||||
: COLORS.lossText}
|
||||
? COLORS.secondary
|
||||
: COLORS.tertiary}
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
let investmentTimelineSvg: Element;
|
||||
let targetDateObject: dayjs.Dayjs;
|
||||
let savingsTotal = 0,
|
||||
investmentTotal = 0,
|
||||
gainTotal = 0,
|
||||
targetSavings = 0,
|
||||
pmt = 0,
|
||||
xirr = 0,
|
||||
|
@ -60,6 +62,8 @@
|
|||
onMount(async () => {
|
||||
({
|
||||
savingsTotal,
|
||||
investmentTotal,
|
||||
gainTotal,
|
||||
savingsTimeline,
|
||||
target: targetSavings,
|
||||
rate,
|
||||
|
@ -113,6 +117,13 @@
|
|||
<div class="container is-fluid">
|
||||
<nav class="level custom-icon {isMobile() && 'grid-2'}">
|
||||
<LevelItem title={name} value={iconGlyph(icon)} />
|
||||
<LevelItem
|
||||
title="Net Investment"
|
||||
value={formatCurrency(investmentTotal)}
|
||||
color={COLORS.secondary}
|
||||
subtitle={`<b>${formatCurrency(gainTotal)}</b> ${gainTotal >= 0 ? "gain" : "loss"}`}
|
||||
/>
|
||||
|
||||
<LevelItem
|
||||
title="Current Savings"
|
||||
value={formatCurrency(savingsTotal)}
|
||||
|
@ -123,7 +134,7 @@
|
|||
<LevelItem
|
||||
title="Target Savings"
|
||||
value={formatCurrency(targetSavings)}
|
||||
color={COLORS.secondary}
|
||||
color={COLORS.primary}
|
||||
subtitle={targetDateObject?.isValid() ? targetDateObject.format("DD MMM YYYY") : null}
|
||||
/>
|
||||
|
||||
|
@ -166,7 +177,7 @@
|
|||
</div>
|
||||
<BoxLabel text="Monthly Investment" />
|
||||
<div class="columns">
|
||||
<div class="column is-12 has-text-centered has-text-grey">
|
||||
<div class="column is-12 has-text-grey">
|
||||
<AssetsBalance breakdowns={balances} indent={false} />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -180,11 +191,11 @@
|
|||
{posting}
|
||||
color={posting.amount >= 0
|
||||
? posting.account.startsWith("Income:CapitalGains")
|
||||
? COLORS.lossText
|
||||
: COLORS.gainText
|
||||
? COLORS.tertiary
|
||||
: COLORS.secondary
|
||||
: posting.account.startsWith("Income:CapitalGains")
|
||||
? COLORS.gainText
|
||||
: COLORS.lossText}
|
||||
? COLORS.secondary
|
||||
: COLORS.tertiary}
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
|
|
|
@ -3,25 +3,21 @@
|
|||
"Assets": {
|
||||
"date": "0001-01-01T00:00:00Z",
|
||||
"account": "Assets",
|
||||
"amount": 0,
|
||||
"market_amount": 0
|
||||
},
|
||||
"Assets:Checking": {
|
||||
"date": "2022-02-07T23:59:59.999999999Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity": {
|
||||
"date": "0001-01-01T00:00:00Z",
|
||||
"account": "Assets:Equity",
|
||||
"amount": 0,
|
||||
"market_amount": 0
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-02-07T23:59:59.999999999Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -30,7 +26,6 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-01T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 11000,
|
||||
"market_amount": 11000
|
||||
}
|
||||
},
|
||||
|
@ -38,7 +33,6 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-02T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 11000,
|
||||
"market_amount": 11000
|
||||
}
|
||||
},
|
||||
|
@ -46,7 +40,6 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-03T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 11000,
|
||||
"market_amount": 11000
|
||||
}
|
||||
},
|
||||
|
@ -54,7 +47,6 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-04T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 11000,
|
||||
"market_amount": 11000
|
||||
}
|
||||
},
|
||||
|
@ -62,13 +54,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-05T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-05T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10005.05
|
||||
}
|
||||
},
|
||||
|
@ -76,13 +66,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-06T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-06T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10005.05
|
||||
}
|
||||
},
|
||||
|
@ -90,13 +78,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-07T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-07T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10005.05
|
||||
}
|
||||
},
|
||||
|
@ -104,13 +90,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-08T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-08T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10005.05
|
||||
}
|
||||
},
|
||||
|
@ -118,13 +102,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-09T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-09T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10005.05
|
||||
}
|
||||
},
|
||||
|
@ -132,13 +114,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-10T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-10T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10005.05
|
||||
}
|
||||
},
|
||||
|
@ -146,13 +126,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-11T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-11T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10005.05
|
||||
}
|
||||
},
|
||||
|
@ -160,13 +138,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-12T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-12T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10005.05
|
||||
}
|
||||
},
|
||||
|
@ -174,13 +150,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-13T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-13T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10005.05
|
||||
}
|
||||
},
|
||||
|
@ -188,13 +162,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-14T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-14T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10005.05
|
||||
}
|
||||
},
|
||||
|
@ -202,13 +174,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-15T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-15T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -216,13 +186,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-16T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-16T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -230,13 +198,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-17T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-17T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -244,13 +210,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-18T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-18T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -258,13 +222,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-19T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-19T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -272,13 +234,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-20T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-20T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -286,13 +246,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-21T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-21T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -300,13 +258,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-22T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-22T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -314,13 +270,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-23T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-23T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -328,13 +282,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-24T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-24T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -342,13 +294,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-25T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-25T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -356,13 +306,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-26T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-26T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -370,13 +318,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-27T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-27T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -384,13 +330,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-28T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-28T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -398,13 +342,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-29T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-29T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -412,13 +354,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-30T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-30T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -426,13 +366,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-31T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-31T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -440,13 +378,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-02-01T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-02-01T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -454,13 +390,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-02-02T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-02-02T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -468,13 +402,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-02-03T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-02-03T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -482,13 +414,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-02-04T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-02-04T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -496,13 +426,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-02-05T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-02-05T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -510,13 +438,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-02-06T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-02-06T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -524,13 +450,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-02-07T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-02-07T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,25 +3,21 @@
|
|||
"Assets": {
|
||||
"date": "0001-01-01T00:00:00Z",
|
||||
"account": "Assets",
|
||||
"amount": 0,
|
||||
"market_amount": 0
|
||||
},
|
||||
"Assets:Checking": {
|
||||
"date": "2022-02-07T23:59:59.999999999Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity": {
|
||||
"date": "0001-01-01T00:00:00Z",
|
||||
"account": "Assets:Equity",
|
||||
"amount": 0,
|
||||
"market_amount": 0
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-02-07T23:59:59.999999999Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -30,7 +26,6 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-01T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 11000,
|
||||
"market_amount": 11000
|
||||
}
|
||||
},
|
||||
|
@ -38,7 +33,6 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-02T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 11000,
|
||||
"market_amount": 11000
|
||||
}
|
||||
},
|
||||
|
@ -46,7 +40,6 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-03T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 11000,
|
||||
"market_amount": 11000
|
||||
}
|
||||
},
|
||||
|
@ -54,7 +47,6 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-04T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 11000,
|
||||
"market_amount": 11000
|
||||
}
|
||||
},
|
||||
|
@ -62,13 +54,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-05T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-05T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10005.05
|
||||
}
|
||||
},
|
||||
|
@ -76,13 +66,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-06T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-06T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10005.05
|
||||
}
|
||||
},
|
||||
|
@ -90,13 +78,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-07T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-07T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10005.05
|
||||
}
|
||||
},
|
||||
|
@ -104,13 +90,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-08T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-08T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10005.05
|
||||
}
|
||||
},
|
||||
|
@ -118,13 +102,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-09T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-09T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10005.05
|
||||
}
|
||||
},
|
||||
|
@ -132,13 +114,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-10T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-10T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10005.05
|
||||
}
|
||||
},
|
||||
|
@ -146,13 +126,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-11T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-11T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10005.05
|
||||
}
|
||||
},
|
||||
|
@ -160,13 +138,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-12T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-12T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10005.05
|
||||
}
|
||||
},
|
||||
|
@ -174,13 +150,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-13T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-13T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10005.05
|
||||
}
|
||||
},
|
||||
|
@ -188,13 +162,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-14T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-14T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10005.05
|
||||
}
|
||||
},
|
||||
|
@ -202,13 +174,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-15T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-15T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -216,13 +186,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-16T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-16T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -230,13 +198,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-17T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-17T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -244,13 +210,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-18T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-18T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -258,13 +222,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-19T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-19T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -272,13 +234,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-20T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-20T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -286,13 +246,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-21T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-21T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -300,13 +258,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-22T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-22T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -314,13 +270,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-23T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-23T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -328,13 +282,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-24T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-24T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -342,13 +294,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-25T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-25T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -356,13 +306,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-26T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-26T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -370,13 +318,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-27T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-27T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -384,13 +330,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-28T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-28T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -398,13 +342,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-29T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-29T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -412,13 +354,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-30T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-30T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -426,13 +366,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-01-31T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-01-31T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -440,13 +378,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-02-01T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-02-01T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -454,13 +390,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-02-02T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-02-02T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -468,13 +402,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-02-03T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-02-03T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -482,13 +414,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-02-04T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-02-04T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -496,13 +426,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-02-05T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-02-05T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -510,13 +438,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-02-06T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-02-06T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
},
|
||||
|
@ -524,13 +450,11 @@
|
|||
"Assets:Checking": {
|
||||
"date": "2022-02-07T00:00:00Z",
|
||||
"account": "Assets:Checking",
|
||||
"amount": 994.95,
|
||||
"market_amount": 994.95
|
||||
},
|
||||
"Assets:Equity:AAPL": {
|
||||
"date": "2022-02-07T00:00:00Z",
|
||||
"account": "Assets:Equity:AAPL",
|
||||
"amount": 10005.05,
|
||||
"market_amount": 10025.05
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue