From ce5516f4ab383c91f783306b35bfcbe3eb611c82 Mon Sep 17 00:00:00 2001 From: Anantha Kumaran Date: Fri, 6 Oct 2023 18:30:59 +0530 Subject: [PATCH] handle european formatting convention --- Makefile | 4 +- internal/ledger/ledger.go | 72 ++- internal/utils/utils.go | 4 + src/lib/utils.ts | 17 +- tests/fixture/eur/allocation.json | 539 +++++++++++++++++++ tests/fixture/eur/assets_balance.json | 48 ++ tests/fixture/eur/budget.json | 5 + tests/fixture/eur/cash_flow.json | 24 + tests/fixture/eur/dashboard.json | 140 +++++ tests/fixture/eur/diagnosis.json | 3 + tests/fixture/eur/expense.json | 177 ++++++ tests/fixture/eur/files.json | 27 + tests/fixture/eur/gain.json | 36 ++ tests/fixture/eur/income.json | 61 +++ tests/fixture/eur/investment.json | 55 ++ tests/fixture/eur/ledger.json | 76 +++ tests/fixture/eur/liabilities_balance.json | 3 + tests/fixture/eur/liabilities_interest.json | 3 + tests/fixture/eur/liabilities_repayment.json | 3 + tests/fixture/eur/main.ledger | 13 + tests/fixture/eur/networth.json | 309 +++++++++++ tests/fixture/eur/paisa.yaml | 5 + tests/fixture/eur/price.json | 22 + tests/fixture/eur/recurring.json | 3 + tests/fixture/eur/retirement.json | 160 ++++++ tests/fixture/eur/transaction.json | 100 ++++ 26 files changed, 1888 insertions(+), 21 deletions(-) create mode 100644 tests/fixture/eur/allocation.json create mode 100644 tests/fixture/eur/assets_balance.json create mode 100644 tests/fixture/eur/budget.json create mode 100644 tests/fixture/eur/cash_flow.json create mode 100644 tests/fixture/eur/dashboard.json create mode 100644 tests/fixture/eur/diagnosis.json create mode 100644 tests/fixture/eur/expense.json create mode 100644 tests/fixture/eur/files.json create mode 100644 tests/fixture/eur/gain.json create mode 100644 tests/fixture/eur/income.json create mode 100644 tests/fixture/eur/investment.json create mode 100644 tests/fixture/eur/ledger.json create mode 100644 tests/fixture/eur/liabilities_balance.json create mode 100644 tests/fixture/eur/liabilities_interest.json create mode 100644 tests/fixture/eur/liabilities_repayment.json create mode 100644 tests/fixture/eur/main.ledger create mode 100644 tests/fixture/eur/networth.json create mode 100644 tests/fixture/eur/paisa.yaml create mode 100644 tests/fixture/eur/price.json create mode 100644 tests/fixture/eur/recurring.json create mode 100644 tests/fixture/eur/retirement.json create mode 100644 tests/fixture/eur/transaction.json diff --git a/Makefile b/Makefile index 3ba0578e..527bf4be 100644 --- a/Makefile +++ b/Makefile @@ -32,12 +32,12 @@ lint: regen: go build - REGENERATE=true TZ=UTC bun test tests + unset PAISA_CONFIG && REGENERATE=true TZ=UTC bun test tests jstest: bun test --preload ./src/happydom.ts src go build - TZ=UTC bun test tests + unset PAISA_CONFIG && TZ=UTC bun test tests jsbuild: npm run build diff --git a/internal/ledger/ledger.go b/internal/ledger/ledger.go index c23da993..a4808f1e 100644 --- a/internal/ledger/ledger.go +++ b/internal/ledger/ledger.go @@ -61,12 +61,12 @@ func (LedgerCLI) ValidateFile(journalPath string) ([]LedgerFileError, string, er var output, error bytes.Buffer err = utils.Exec(ledgerPath, &output, &error, "--args-only", "-f", journalPath, "balance") if err == nil { - return errors, output.String(), nil + return errors, utils.Dos2Unix(output.String()), nil } - re := regexp.MustCompile(`(?m)While parsing file "[^"]+", line ([0-9]+):\s*[\r\n]+(?:(?:While|>).*[\r\n]+)*((?:.*[\r\n]+)*?Error: .*[\r\n]+)`) + re := regexp.MustCompile(`(?m)While parsing file "[^"]+", line ([0-9]+):\s*\n(?:(?:While|>).*\n)*((?:.*\n)*?Error: .*\n)`) - matches := re.FindAllStringSubmatch(error.String(), -1) + matches := re.FindAllStringSubmatch(utils.Dos2Unix(error.String()), -1) for _, match := range matches { line, _ := strconv.ParseUint(match[1], 10, 64) @@ -105,12 +105,13 @@ func (LedgerCLI) Prices(journalPath string) ([]price.Price, error) { } var output, error bytes.Buffer - err = utils.Exec(ledgerPath, &output, &error, "--args-only", "-f", journalPath, "pricesdb") + err = utils.Exec(ledgerPath, &output, &error, "--args-only", "-f", journalPath, "pricesdb", "--pricedb-format", "P %(datetime) %(display_account) %(quantity(scrub(display_amount))) %(commodity(scrub(display_amount)))\n") if err != nil { + log.Error(error.String()) return prices, err } - return parseLedgerPrices(output.String(), config.DefaultCurrency()) + return parseLedgerPrices(utils.Dos2Unix(output.String()), config.DefaultCurrency()) } func (HLedgerCLI) ValidateFile(journalPath string) ([]LedgerFileError, string, error) { @@ -123,11 +124,11 @@ func (HLedgerCLI) ValidateFile(journalPath string) ([]LedgerFileError, string, e var output, error bytes.Buffer err = utils.Exec(path, &output, &error, "-f", journalPath, "--auto", "balance") if err == nil { - return errors, output.String(), nil + return errors, utils.Dos2Unix(output.String()), nil } - re := regexp.MustCompile(`(?m)hledger: Error: [^:]*:([0-9:-]+)[\r\n]+((?:.*[\r\n]+)*)`) - matches := re.FindAllStringSubmatch(error.String(), -1) + re := regexp.MustCompile(`(?m)hledger: Error: [^:]*:([0-9:-]+)\n((?:.*\n)*)`) + matches := re.FindAllStringSubmatch(utils.Dos2Unix(error.String()), -1) for _, match := range matches { lineRange := match[1] @@ -179,18 +180,55 @@ func (HLedgerCLI) Prices(journalPath string) ([]price.Price, error) { return prices, err } + commodities, err := parseHLedgerCommodities(journalPath) + if err != nil { + log.Error(err) + return prices, err + } + + commoditiesStyles := lo.Map(commodities, func(c string, _ int) string { + return fmt.Sprintf(`--commodity-style="%s" 1,000.00`, c) + }) + + args := append([]string{"-f", journalPath, "--infer-market-prices", "--infer-costs", "prices"}, commoditiesStyles...) + var output, error bytes.Buffer - err = utils.Exec(path, &output, &error, "-f", journalPath, "--auto", "--infer-market-prices", "--infer-costs", "prices") + err = utils.Exec(path, &output, &error, args...) if err != nil { + log.Error(error.String()) return prices, err } - return parseHLedgerPrices(output.String(), config.DefaultCurrency()) + return parseHLedgerPrices(utils.Dos2Unix(output.String()), config.DefaultCurrency()) +} + +func parseHLedgerCommodities(journalPath string) ([]string, error) { + var commodities []string + + path, err := binary.LookPath("hledger") + if err != nil { + return commodities, err + } + + var output, error bytes.Buffer + err = utils.Exec(path, &output, &error, "-f", journalPath, "commodities") + if err != nil { + log.Error(error.String()) + return commodities, err + } + + lines := strings.Split(utils.Dos2Unix(output.String()), "\n") + + for _, line := range lines { + commodities = append(commodities, utils.UnQuote(strings.TrimSpace(line))) + } + + return commodities, nil } func parseLedgerPrices(output string, defaultCurrency string) ([]price.Price, error) { var prices []price.Price - re := regexp.MustCompile(`P (\d{4}\/\d{2}\/\d{2}) (?:\d{2}:\d{2}:\d{2}) ([^\s\d.-]+|"[^"]+") ([^\r\n]+)[\r\n]+`) + re := regexp.MustCompile(`P (\d{4}\/\d{2}\/\d{2}) (?:\d{2}:\d{2}:\d{2}) ([^\s\d.-]+|"[^"]+") ([^\n]+)\n`) matches := re.FindAllStringSubmatch(output, -1) for _, match := range matches { @@ -218,7 +256,7 @@ func parseLedgerPrices(output string, defaultCurrency string) ([]price.Price, er func parseHLedgerPrices(output string, defaultCurrency string) ([]price.Price, error) { var prices []price.Price - re := regexp.MustCompile(`P (\d{4}-\d{2}-\d{2}) ([^\s\d.-]+|"[^"]+") ([^\r\n]+)[\r\n]+`) + re := regexp.MustCompile(`P (\d{4}-\d{2}-\d{2}) ([^\s\d.-]+|"[^"]+") ([^\n]+)\n`) matches := re.FindAllStringSubmatch(output, -1) for _, match := range matches { @@ -282,10 +320,11 @@ func execLedgerCommand(journalPath string, flags []string) ([]*posting.Posting, TransactionBeginLine TransactionEndLine LotPrice + LotCommodity TagRecurring TagPeriod ) - args := append(append([]string{"--args-only", "-f", journalPath}, flags...), "csv", "--csv-format", "%(quoted(date)),%(quoted(payee)),%(quoted(display_account)),%(quoted(commodity(scrub(display_amount)))),%(quoted(quantity(scrub(display_amount)))),%(quoted(scrub(market(amount,date,'"+config.DefaultCurrency()+"') * 100000000))),%(quoted(xact.filename)),%(quoted(xact.id)),%(quoted(cleared ? \"*\" : (pending ? \"!\" : \"\"))),%(quoted(xact.beg_line)),%(quoted(xact.end_line)),%(quoted(lot_price(amount))),%(quoted(tag('Recurring'))),%(quoted(tag('Period')))\n") + args := append(append([]string{"--args-only", "-f", journalPath}, flags...), "csv", "--csv-format", "%(quoted(date)),%(quoted(payee)),%(quoted(display_account)),%(quoted(commodity(scrub(display_amount)))),%(quoted(quantity(scrub(display_amount)))),%(quoted(quantity(scrub(market(amount,date,'"+config.DefaultCurrency()+"') * 100000000)))),%(quoted(xact.filename)),%(quoted(xact.id)),%(quoted(cleared ? \"*\" : (pending ? \"!\" : \"\"))),%(quoted(xact.beg_line)),%(quoted(xact.end_line)),%(quoted(quantity(lot_price(amount)))),%(quoted(commodity(lot_price(amount)))),%(quoted(tag('Recurring'))),%(quoted(tag('Period')))\n") ledgerPath, err := binary.LedgerBinaryPath() if err != nil { @@ -324,12 +363,13 @@ func execLedgerCommand(journalPath string, flags []string) ([]*posting.Posting, amountAvailable := false lotString := record[LotPrice] - if lotString != "" { - lotCurrency, lotAmount, err := parseAmount(record[LotPrice]) + if lotString != "" && lotString != "0" { + lotAmount, err := decimal.NewFromString(record[LotPrice]) if err != nil { return nil, err } + lotCurrency := utils.UnQuote(record[LotCommodity]) if lotCurrency == config.DefaultCurrency() { amount = lotAmount.Mul(quantity) amountAvailable = true @@ -337,7 +377,7 @@ func execLedgerCommand(journalPath string, flags []string) ([]*posting.Posting, } if !amountAvailable { - _, amount, err = parseAmount(record[Amount]) + amount, err = decimal.NewFromString(record[Amount]) if err != nil { return nil, err } diff --git a/internal/utils/utils.go b/internal/utils/utils.go index b4c1563c..edf1c6cc 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -221,3 +221,7 @@ func OpenDB() (*gorm.DB, error) { db, err := gorm.Open(sqlite.Open(config.GetDBPath()), &gorm.Config{Logger: gorm_logrus.New()}) return db, err } + +func Dos2Unix(str string) string { + return strings.ReplaceAll(str, "\r\n", "\n") +} diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 0c984eac..320b6292 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -1,5 +1,4 @@ import dayjs, { Dayjs } from "dayjs"; -import { sprintf } from "sprintf-js"; import _ from "lodash"; import * as d3 from "d3"; import { loading } from "../store"; @@ -670,7 +669,10 @@ export function formatFloat(value: number, precision = 2) { if (obscure()) { return "00"; } - return sprintf(`%.${precision}f`, value); + return value.toLocaleString(USER_CONFIG.locale, { + minimumFractionDigits: precision, + maximumFractionDigits: precision + }); } export function formatPercentage(value: number, precision = 0) { @@ -697,7 +699,16 @@ export function formatFixedWidthFloat(value: number, width: number, precision = if (obscure()) { value = 0; } - return sprintf(`%${width}.${precision}f`, value); + + const formatted = value.toLocaleString(USER_CONFIG.locale, { + minimumFractionDigits: precision, + maximumFractionDigits: precision + }); + + if (formatted.length < width) { + return formatted.padStart(width, " "); + } + return formatted; } export function forEachMonth( diff --git a/tests/fixture/eur/allocation.json b/tests/fixture/eur/allocation.json new file mode 100644 index 00000000..89f3bc22 --- /dev/null +++ b/tests/fixture/eur/allocation.json @@ -0,0 +1,539 @@ +{ + "aggregates": { + "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 + } + }, + "aggregates_timeline": [ + { + "Assets:Checking": { + "date": "2022-01-01T00:00:00Z", + "account": "Assets:Checking", + "amount": 11000, + "market_amount": 11000 + } + }, + { + "Assets:Checking": { + "date": "2022-01-02T00:00:00Z", + "account": "Assets:Checking", + "amount": 11000, + "market_amount": 11000 + } + }, + { + "Assets:Checking": { + "date": "2022-01-03T00:00:00Z", + "account": "Assets:Checking", + "amount": 11000, + "market_amount": 11000 + } + }, + { + "Assets:Checking": { + "date": "2022-01-04T00:00:00Z", + "account": "Assets:Checking", + "amount": 11000, + "market_amount": 11000 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + }, + { + "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 + } + } + ], + "allocation_targets": null +} \ No newline at end of file diff --git a/tests/fixture/eur/assets_balance.json b/tests/fixture/eur/assets_balance.json new file mode 100644 index 00000000..9a950862 --- /dev/null +++ b/tests/fixture/eur/assets_balance.json @@ -0,0 +1,48 @@ +{ + "asset_breakdowns": { + "Assets": { + "group": "Assets", + "investmentAmount": 10005.05, + "withdrawalAmount": 0, + "marketAmount": 11020, + "balanceUnits": 0, + "latestPrice": 0, + "xirr": 1.76, + "gainAmount": 1014.95, + "absoluteReturn": 0.1014 + }, + "Assets:Checking": { + "group": "Assets:Checking", + "investmentAmount": 0, + "withdrawalAmount": 0, + "marketAmount": 994.95, + "balanceUnits": 0, + "latestPrice": 0, + "xirr": 0, + "gainAmount": 994.95, + "absoluteReturn": 0 + }, + "Assets:Equity": { + "group": "Assets:Equity", + "investmentAmount": 10005.05, + "withdrawalAmount": 0, + "marketAmount": 10025.05, + "balanceUnits": 0, + "latestPrice": 0, + "xirr": 2.17, + "gainAmount": 20, + "absoluteReturn": 0.002 + }, + "Assets:Equity:AAPL": { + "group": "Assets:Equity:AAPL", + "investmentAmount": 10005.05, + "withdrawalAmount": 0, + "marketAmount": 10025.05, + "balanceUnits": 1, + "latestPrice": 0, + "xirr": 2.17, + "gainAmount": 20, + "absoluteReturn": 0.002 + } + } +} \ No newline at end of file diff --git a/tests/fixture/eur/budget.json b/tests/fixture/eur/budget.json new file mode 100644 index 00000000..a50f8ad2 --- /dev/null +++ b/tests/fixture/eur/budget.json @@ -0,0 +1,5 @@ +{ + "availableForBudgeting": 994.95, + "budgetsByMonth": {}, + "checkingBalance": 994.95 +} \ No newline at end of file diff --git a/tests/fixture/eur/cash_flow.json b/tests/fixture/eur/cash_flow.json new file mode 100644 index 00000000..017e6894 --- /dev/null +++ b/tests/fixture/eur/cash_flow.json @@ -0,0 +1,24 @@ +{ + "cash_flows": [ + { + "date": "2022-01-01T00:00:00Z", + "income": 11000, + "expenses": 0, + "liabilities": 0, + "investment": 10005.05, + "tax": 0, + "checking": 994.95, + "balance": 994.95 + }, + { + "date": "2022-02-01T00:00:00Z", + "income": 0, + "expenses": 0, + "liabilities": 0, + "investment": 0, + "tax": 0, + "checking": 0, + "balance": 994.95 + } + ] +} \ No newline at end of file diff --git a/tests/fixture/eur/dashboard.json b/tests/fixture/eur/dashboard.json new file mode 100644 index 00000000..a48c3a2a --- /dev/null +++ b/tests/fixture/eur/dashboard.json @@ -0,0 +1,140 @@ +{ + "budget": { + "availableForBudgeting": 994.95, + "budgetsByMonth": {}, + "checkingBalance": 994.95 + }, + "cashFlows": [ + { + "date": "2022-01-01T00:00:00Z", + "income": 11000, + "expenses": 0, + "liabilities": 0, + "investment": 10005.05, + "tax": 0, + "checking": 994.95, + "balance": 994.95 + }, + { + "date": "2022-02-01T00:00:00Z", + "income": 0, + "expenses": 0, + "liabilities": 0, + "investment": 0, + "tax": 0, + "checking": 0, + "balance": 994.95 + } + ], + "expenses": {}, + "networth": { + "networth": { + "date": "2022-02-07T23:59:59.999999999Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 20, + "balanceAmount": 11020, + "netInvestmentAmount": 11000 + }, + "xirr": 1.76 + }, + "transactionSequences": [], + "transactions": [ + { + "id": "2", + "date": "2022-01-05T00:00:00Z", + "payee": "Buy stock", + "postings": [ + { + "id": 3, + "transaction_id": "2", + "date": "2022-01-05T00:00:00Z", + "payee": "Buy stock", + "account": "Assets:Equity:AAPL", + "commodity": "AAPL", + "quantity": 1, + "amount": 10005.05, + "status": "unmarked", + "tag_recurring": "", + "tag_period": "", + "transaction_begin_line": 11, + "transaction_end_line": 14, + "file_name": "main.ledger", + "forecast": false, + "market_amount": 0 + }, + { + "id": 4, + "transaction_id": "2", + "date": "2022-01-05T00:00:00Z", + "payee": "Buy stock", + "account": "Assets:Checking", + "commodity": "EUR", + "quantity": -10005.05, + "amount": -10005.05, + "status": "unmarked", + "tag_recurring": "", + "tag_period": "", + "transaction_begin_line": 11, + "transaction_end_line": 14, + "file_name": "main.ledger", + "forecast": false, + "market_amount": 0 + } + ], + "tag_recurring": "", + "tag_period": "", + "beginLine": 11, + "endLine": 14, + "fileName": "main.ledger" + }, + { + "id": "1", + "date": "2022-01-01T00:00:00Z", + "payee": "Salary", + "postings": [ + { + "id": 2, + "transaction_id": "1", + "date": "2022-01-01T00:00:00Z", + "payee": "Salary", + "account": "Assets:Checking", + "commodity": "EUR", + "quantity": 11000, + "amount": 11000, + "status": "unmarked", + "tag_recurring": "", + "tag_period": "", + "transaction_begin_line": 4, + "transaction_end_line": 7, + "file_name": "main.ledger", + "forecast": false, + "market_amount": 0 + }, + { + "id": 1, + "transaction_id": "1", + "date": "2022-01-01T00:00:00Z", + "payee": "Salary", + "account": "Income:Salary:Acme", + "commodity": "EUR", + "quantity": -11000, + "amount": -11000, + "status": "unmarked", + "tag_recurring": "", + "tag_period": "", + "transaction_begin_line": 4, + "transaction_end_line": 7, + "file_name": "main.ledger", + "forecast": false, + "market_amount": 0 + } + ], + "tag_recurring": "", + "tag_period": "", + "beginLine": 4, + "endLine": 7, + "fileName": "main.ledger" + } + ] +} \ No newline at end of file diff --git a/tests/fixture/eur/diagnosis.json b/tests/fixture/eur/diagnosis.json new file mode 100644 index 00000000..18b086be --- /dev/null +++ b/tests/fixture/eur/diagnosis.json @@ -0,0 +1,3 @@ +{ + "issues": [] +} \ No newline at end of file diff --git a/tests/fixture/eur/expense.json b/tests/fixture/eur/expense.json new file mode 100644 index 00000000..800eab2e --- /dev/null +++ b/tests/fixture/eur/expense.json @@ -0,0 +1,177 @@ +{ + "expenses": [], + "graph": { + "2021 - 22": { + "flat": { + "nodes": [ + { + "id": 1, + "name": "Assets:Checking" + }, + { + "id": 3, + "name": "Assets:Equity:AAPL" + }, + { + "id": 2, + "name": "Income:Salary:Acme" + } + ], + "links": [ + { + "source": 1, + "target": 3, + "value": 10005.05 + }, + { + "source": 2, + "target": 1, + "value": 11000 + } + ] + }, + "hierarchy": { + "nodes": [ + { + "id": 1, + "name": "Assets:Checking" + }, + { + "id": 5, + "name": "Assets:Equity:AAPL" + }, + { + "id": 2, + "name": "Income" + }, + { + "id": 3, + "name": "Income:Salary" + }, + { + "id": 4, + "name": "Income:Salary:Acme" + } + ], + "links": [ + { + "source": 1, + "target": 5, + "value": 10005.05 + }, + { + "source": 2, + "target": 1, + "value": 11000 + }, + { + "source": 3, + "target": 2, + "value": 11000 + }, + { + "source": 4, + "target": 3, + "value": 11000 + } + ] + } + } + }, + "month_wise": { + "expenses": {}, + "incomes": { + "2022-01": [ + { + "id": 1, + "transaction_id": "1", + "date": "2022-01-01T00:00:00Z", + "payee": "Salary", + "account": "Income:Salary:Acme", + "commodity": "EUR", + "quantity": -11000, + "amount": -11000, + "status": "unmarked", + "tag_recurring": "", + "tag_period": "", + "transaction_begin_line": 4, + "transaction_end_line": 7, + "file_name": "main.ledger", + "forecast": false, + "market_amount": 0 + } + ] + }, + "investments": { + "2022-01": [ + { + "id": 3, + "transaction_id": "2", + "date": "2022-01-05T00:00:00Z", + "payee": "Buy stock", + "account": "Assets:Equity:AAPL", + "commodity": "AAPL", + "quantity": 1, + "amount": 10005.05, + "status": "unmarked", + "tag_recurring": "", + "tag_period": "", + "transaction_begin_line": 11, + "transaction_end_line": 14, + "file_name": "main.ledger", + "forecast": false, + "market_amount": 0 + } + ] + }, + "taxes": {} + }, + "year_wise": { + "expenses": {}, + "incomes": { + "2021 - 22": [ + { + "id": 1, + "transaction_id": "1", + "date": "2022-01-01T00:00:00Z", + "payee": "Salary", + "account": "Income:Salary:Acme", + "commodity": "EUR", + "quantity": -11000, + "amount": -11000, + "status": "unmarked", + "tag_recurring": "", + "tag_period": "", + "transaction_begin_line": 4, + "transaction_end_line": 7, + "file_name": "main.ledger", + "forecast": false, + "market_amount": 0 + } + ] + }, + "investments": { + "2021 - 22": [ + { + "id": 3, + "transaction_id": "2", + "date": "2022-01-05T00:00:00Z", + "payee": "Buy stock", + "account": "Assets:Equity:AAPL", + "commodity": "AAPL", + "quantity": 1, + "amount": 10005.05, + "status": "unmarked", + "tag_recurring": "", + "tag_period": "", + "transaction_begin_line": 11, + "transaction_end_line": 14, + "file_name": "main.ledger", + "forecast": false, + "market_amount": 0 + } + ] + }, + "taxes": {} + } +} \ No newline at end of file diff --git a/tests/fixture/eur/files.json b/tests/fixture/eur/files.json new file mode 100644 index 00000000..0cbdd904 --- /dev/null +++ b/tests/fixture/eur/files.json @@ -0,0 +1,27 @@ +{ + "accounts": [ + "Income:Salary:Acme", + "Assets:Checking", + "Assets:Equity:AAPL" + ], + "commodities": [ + "EUR", + "AAPL" + ], + "files": [ + { + "name": "main.ledger", + "content": "commodity EUR\n\tformat 1.000,00 EUR\n\n2022/01/01 Salary\n Income:Salary:Acme -11.000,00 EUR\n Assets:Checking 11.000,00 EUR\n\nP 2022/01/05 00:00:00 AAPL 10.005,05 EUR\nP 2022/01/15 00:00:00 AAPL 10.025,05 EUR\n\n2022/01/05 Buy stock\n Assets:Equity:AAPL 1 AAPL @ 10.005,05 EUR\n Assets:Checking -10.005,05 EUR\n", + "versions": [ + "main.ledger.backup.2023-10-07-03-07-18.236", + "main.ledger.backup.2023-10-07-03-06-29.721", + "main.ledger.backup.2023-10-07-03-04-56.697" + ], + "operation": "" + } + ], + "payees": [ + "Salary", + "Buy stock" + ] +} \ No newline at end of file diff --git a/tests/fixture/eur/gain.json b/tests/fixture/eur/gain.json new file mode 100644 index 00000000..fb3b70be --- /dev/null +++ b/tests/fixture/eur/gain.json @@ -0,0 +1,36 @@ +{ + "gain_breakdown": [ + { + "account": "Assets:Equity:AAPL", + "networth": { + "date": "2022-02-07T23:59:59.999999999Z", + "investmentAmount": 10005.05, + "withdrawalAmount": 0, + "gainAmount": 20, + "balanceAmount": 10025.05, + "netInvestmentAmount": 10005.05 + }, + "xirr": 2.17, + "postings": [ + { + "id": 3, + "transaction_id": "2", + "date": "2022-01-05T00:00:00Z", + "payee": "Buy stock", + "account": "Assets:Equity:AAPL", + "commodity": "AAPL", + "quantity": 1, + "amount": 10005.05, + "status": "unmarked", + "tag_recurring": "", + "tag_period": "", + "transaction_begin_line": 11, + "transaction_end_line": 14, + "file_name": "main.ledger", + "forecast": false, + "market_amount": 10025.05 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/fixture/eur/income.json b/tests/fixture/eur/income.json new file mode 100644 index 00000000..c417a57d --- /dev/null +++ b/tests/fixture/eur/income.json @@ -0,0 +1,61 @@ +{ + "income_timeline": [ + { + "date": "2022-01-01T00:00:00Z", + "postings": [ + { + "id": 1, + "transaction_id": "1", + "date": "2022-01-01T00:00:00Z", + "payee": "Salary", + "account": "Income:Salary:Acme", + "commodity": "EUR", + "quantity": -11000, + "amount": -11000, + "status": "unmarked", + "tag_recurring": "", + "tag_period": "", + "transaction_begin_line": 4, + "transaction_end_line": 7, + "file_name": "main.ledger", + "forecast": false, + "market_amount": 0 + } + ] + }, + { + "date": "2022-02-01T00:00:00Z", + "postings": [] + } + ], + "tax_timeline": [], + "yearly_cards": [ + { + "start_date": "2021-04-01T00:00:00Z", + "end_date": "2022-03-31T23:59:59.999999999Z", + "postings": [ + { + "id": 1, + "transaction_id": "1", + "date": "2022-01-01T00:00:00Z", + "payee": "Salary", + "account": "Income:Salary:Acme", + "commodity": "EUR", + "quantity": -11000, + "amount": -11000, + "status": "unmarked", + "tag_recurring": "", + "tag_period": "", + "transaction_begin_line": 4, + "transaction_end_line": 7, + "file_name": "main.ledger", + "forecast": false, + "market_amount": 0 + } + ], + "gross_income": 11000, + "net_tax": 0, + "net_income": 11000 + } + ] +} \ No newline at end of file diff --git a/tests/fixture/eur/investment.json b/tests/fixture/eur/investment.json new file mode 100644 index 00000000..3b565ea9 --- /dev/null +++ b/tests/fixture/eur/investment.json @@ -0,0 +1,55 @@ +{ + "assets": [ + { + "id": 3, + "transaction_id": "2", + "date": "2022-01-05T00:00:00Z", + "payee": "Buy stock", + "account": "Assets:Equity:AAPL", + "commodity": "AAPL", + "quantity": 1, + "amount": 10005.05, + "status": "unmarked", + "tag_recurring": "", + "tag_period": "", + "transaction_begin_line": 11, + "transaction_end_line": 14, + "file_name": "main.ledger", + "forecast": false, + "market_amount": 0 + } + ], + "yearly_cards": [ + { + "start_date": "2021-04-01T00:00:00Z", + "end_date": "2022-03-31T23:59:59.999999999Z", + "postings": [ + { + "id": 3, + "transaction_id": "2", + "date": "2022-01-05T00:00:00Z", + "payee": "Buy stock", + "account": "Assets:Equity:AAPL", + "commodity": "AAPL", + "quantity": 1, + "amount": 10005.05, + "status": "unmarked", + "tag_recurring": "", + "tag_period": "", + "transaction_begin_line": 11, + "transaction_end_line": 14, + "file_name": "main.ledger", + "forecast": false, + "market_amount": 0 + } + ], + "gross_salary_income": 11000, + "gross_other_income": 0, + "net_tax": 0, + "net_income": 11000, + "net_investment": 10005.05, + "net_expense": 0, + "savings_rate": 90.955 + } + ] +} \ No newline at end of file diff --git a/tests/fixture/eur/ledger.json b/tests/fixture/eur/ledger.json new file mode 100644 index 00000000..068af377 --- /dev/null +++ b/tests/fixture/eur/ledger.json @@ -0,0 +1,76 @@ +{ + "postings": [ + { + "id": 3, + "transaction_id": "2", + "date": "2022-01-05T00:00:00Z", + "payee": "Buy stock", + "account": "Assets:Equity:AAPL", + "commodity": "AAPL", + "quantity": 1, + "amount": 10005.05, + "status": "unmarked", + "tag_recurring": "", + "tag_period": "", + "transaction_begin_line": 11, + "transaction_end_line": 14, + "file_name": "main.ledger", + "forecast": false, + "market_amount": 10025.05 + }, + { + "id": 4, + "transaction_id": "2", + "date": "2022-01-05T00:00:00Z", + "payee": "Buy stock", + "account": "Assets:Checking", + "commodity": "EUR", + "quantity": -10005.05, + "amount": -10005.05, + "status": "unmarked", + "tag_recurring": "", + "tag_period": "", + "transaction_begin_line": 11, + "transaction_end_line": 14, + "file_name": "main.ledger", + "forecast": false, + "market_amount": -10005.05 + }, + { + "id": 2, + "transaction_id": "1", + "date": "2022-01-01T00:00:00Z", + "payee": "Salary", + "account": "Assets:Checking", + "commodity": "EUR", + "quantity": 11000, + "amount": 11000, + "status": "unmarked", + "tag_recurring": "", + "tag_period": "", + "transaction_begin_line": 4, + "transaction_end_line": 7, + "file_name": "main.ledger", + "forecast": false, + "market_amount": 11000 + }, + { + "id": 1, + "transaction_id": "1", + "date": "2022-01-01T00:00:00Z", + "payee": "Salary", + "account": "Income:Salary:Acme", + "commodity": "EUR", + "quantity": -11000, + "amount": -11000, + "status": "unmarked", + "tag_recurring": "", + "tag_period": "", + "transaction_begin_line": 4, + "transaction_end_line": 7, + "file_name": "main.ledger", + "forecast": false, + "market_amount": -11000 + } + ] +} \ No newline at end of file diff --git a/tests/fixture/eur/liabilities_balance.json b/tests/fixture/eur/liabilities_balance.json new file mode 100644 index 00000000..25e3825c --- /dev/null +++ b/tests/fixture/eur/liabilities_balance.json @@ -0,0 +1,3 @@ +{ + "liability_breakdowns": {} +} \ No newline at end of file diff --git a/tests/fixture/eur/liabilities_interest.json b/tests/fixture/eur/liabilities_interest.json new file mode 100644 index 00000000..3936c0ad --- /dev/null +++ b/tests/fixture/eur/liabilities_interest.json @@ -0,0 +1,3 @@ +{ + "interest_timeline_breakdown": null +} \ No newline at end of file diff --git a/tests/fixture/eur/liabilities_repayment.json b/tests/fixture/eur/liabilities_repayment.json new file mode 100644 index 00000000..b95d9ac5 --- /dev/null +++ b/tests/fixture/eur/liabilities_repayment.json @@ -0,0 +1,3 @@ +{ + "repayments": [] +} \ No newline at end of file diff --git a/tests/fixture/eur/main.ledger b/tests/fixture/eur/main.ledger new file mode 100644 index 00000000..18f0d4db --- /dev/null +++ b/tests/fixture/eur/main.ledger @@ -0,0 +1,13 @@ +commodity EUR + format 1.000,00 EUR + +2022/01/01 Salary + Income:Salary:Acme -11.000,00 EUR + Assets:Checking 11.000,00 EUR + +P 2022/01/05 00:00:00 AAPL 10.005,05 EUR +P 2022/01/15 00:00:00 AAPL 10.025,05 EUR + +2022/01/05 Buy stock + Assets:Equity:AAPL 1 AAPL @ 10.005,05 EUR + Assets:Checking -10.005,05 EUR diff --git a/tests/fixture/eur/networth.json b/tests/fixture/eur/networth.json new file mode 100644 index 00000000..9b9d2600 --- /dev/null +++ b/tests/fixture/eur/networth.json @@ -0,0 +1,309 @@ +{ + "networthTimeline": [ + { + "date": "2022-01-01T00:00:00Z", + "investmentAmount": 11000, + "withdrawalAmount": 0, + "gainAmount": 0, + "balanceAmount": 11000, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-02T00:00:00Z", + "investmentAmount": 11000, + "withdrawalAmount": 0, + "gainAmount": 0, + "balanceAmount": 11000, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-03T00:00:00Z", + "investmentAmount": 11000, + "withdrawalAmount": 0, + "gainAmount": 0, + "balanceAmount": 11000, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-04T00:00:00Z", + "investmentAmount": 11000, + "withdrawalAmount": 0, + "gainAmount": 0, + "balanceAmount": 11000, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-05T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 0, + "balanceAmount": 11000, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-06T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 0, + "balanceAmount": 11000, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-07T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 0, + "balanceAmount": 11000, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-08T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 0, + "balanceAmount": 11000, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-09T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 0, + "balanceAmount": 11000, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-10T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 0, + "balanceAmount": 11000, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-11T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 0, + "balanceAmount": 11000, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-12T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 0, + "balanceAmount": 11000, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-13T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 0, + "balanceAmount": 11000, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-14T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 0, + "balanceAmount": 11000, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-15T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 20, + "balanceAmount": 11020, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-16T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 20, + "balanceAmount": 11020, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-17T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 20, + "balanceAmount": 11020, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-18T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 20, + "balanceAmount": 11020, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-19T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 20, + "balanceAmount": 11020, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-20T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 20, + "balanceAmount": 11020, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-21T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 20, + "balanceAmount": 11020, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-22T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 20, + "balanceAmount": 11020, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-23T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 20, + "balanceAmount": 11020, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-24T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 20, + "balanceAmount": 11020, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-25T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 20, + "balanceAmount": 11020, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-26T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 20, + "balanceAmount": 11020, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-27T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 20, + "balanceAmount": 11020, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-28T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 20, + "balanceAmount": 11020, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-29T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 20, + "balanceAmount": 11020, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-30T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 20, + "balanceAmount": 11020, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-01-31T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 20, + "balanceAmount": 11020, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-02-01T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 20, + "balanceAmount": 11020, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-02-02T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 20, + "balanceAmount": 11020, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-02-03T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 20, + "balanceAmount": 11020, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-02-04T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 20, + "balanceAmount": 11020, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-02-05T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 20, + "balanceAmount": 11020, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-02-06T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 20, + "balanceAmount": 11020, + "netInvestmentAmount": 11000 + }, + { + "date": "2022-02-07T00:00:00Z", + "investmentAmount": 21005.05, + "withdrawalAmount": 10005.05, + "gainAmount": 20, + "balanceAmount": 11020, + "netInvestmentAmount": 11000 + } + ], + "xirr": 1.76 +} \ No newline at end of file diff --git a/tests/fixture/eur/paisa.yaml b/tests/fixture/eur/paisa.yaml new file mode 100644 index 00000000..3e1aa4e0 --- /dev/null +++ b/tests/fixture/eur/paisa.yaml @@ -0,0 +1,5 @@ +journal_path: main.ledger +db_path: paisa.db +ledger_cli: ledger +default_currency: EUR +locale: es-EU diff --git a/tests/fixture/eur/price.json b/tests/fixture/eur/price.json new file mode 100644 index 00000000..74558d4c --- /dev/null +++ b/tests/fixture/eur/price.json @@ -0,0 +1,22 @@ +{ + "prices": { + "AAPL": [ + { + "id": 3, + "date": "2022-01-15T00:00:00Z", + "commodity_type": "unknown", + "commodity_id": "AAPL", + "commodity_name": "AAPL", + "value": 10025.05 + }, + { + "id": 2, + "date": "2022-01-05T00:00:00Z", + "commodity_type": "unknown", + "commodity_id": "AAPL", + "commodity_name": "AAPL", + "value": 10005.05 + } + ] + } +} \ No newline at end of file diff --git a/tests/fixture/eur/recurring.json b/tests/fixture/eur/recurring.json new file mode 100644 index 00000000..5e86a101 --- /dev/null +++ b/tests/fixture/eur/recurring.json @@ -0,0 +1,3 @@ +{ + "transaction_sequences": [] +} \ No newline at end of file diff --git a/tests/fixture/eur/retirement.json b/tests/fixture/eur/retirement.json new file mode 100644 index 00000000..f1126c96 --- /dev/null +++ b/tests/fixture/eur/retirement.json @@ -0,0 +1,160 @@ +{ + "savings_timeline": [ + { + "date": "2022-01-01T00:00:00Z", + "value": 11000 + }, + { + "date": "2022-01-02T00:00:00Z", + "value": 11000 + }, + { + "date": "2022-01-03T00:00:00Z", + "value": 11000 + }, + { + "date": "2022-01-04T00:00:00Z", + "value": 11000 + }, + { + "date": "2022-01-05T00:00:00Z", + "value": 11000 + }, + { + "date": "2022-01-06T00:00:00Z", + "value": 11000 + }, + { + "date": "2022-01-07T00:00:00Z", + "value": 11000 + }, + { + "date": "2022-01-08T00:00:00Z", + "value": 11000 + }, + { + "date": "2022-01-09T00:00:00Z", + "value": 11000 + }, + { + "date": "2022-01-10T00:00:00Z", + "value": 11000 + }, + { + "date": "2022-01-11T00:00:00Z", + "value": 11000 + }, + { + "date": "2022-01-12T00:00:00Z", + "value": 11000 + }, + { + "date": "2022-01-13T00:00:00Z", + "value": 11000 + }, + { + "date": "2022-01-14T00:00:00Z", + "value": 11000 + }, + { + "date": "2022-01-15T00:00:00Z", + "value": 11020 + }, + { + "date": "2022-01-16T00:00:00Z", + "value": 11020 + }, + { + "date": "2022-01-17T00:00:00Z", + "value": 11020 + }, + { + "date": "2022-01-18T00:00:00Z", + "value": 11020 + }, + { + "date": "2022-01-19T00:00:00Z", + "value": 11020 + }, + { + "date": "2022-01-20T00:00:00Z", + "value": 11020 + }, + { + "date": "2022-01-21T00:00:00Z", + "value": 11020 + }, + { + "date": "2022-01-22T00:00:00Z", + "value": 11020 + }, + { + "date": "2022-01-23T00:00:00Z", + "value": 11020 + }, + { + "date": "2022-01-24T00:00:00Z", + "value": 11020 + }, + { + "date": "2022-01-25T00:00:00Z", + "value": 11020 + }, + { + "date": "2022-01-26T00:00:00Z", + "value": 11020 + }, + { + "date": "2022-01-27T00:00:00Z", + "value": 11020 + }, + { + "date": "2022-01-28T00:00:00Z", + "value": 11020 + }, + { + "date": "2022-01-29T00:00:00Z", + "value": 11020 + }, + { + "date": "2022-01-30T00:00:00Z", + "value": 11020 + }, + { + "date": "2022-01-31T00:00:00Z", + "value": 11020 + }, + { + "date": "2022-02-01T00:00:00Z", + "value": 11020 + }, + { + "date": "2022-02-02T00:00:00Z", + "value": 11020 + }, + { + "date": "2022-02-03T00:00:00Z", + "value": 11020 + }, + { + "date": "2022-02-04T00:00:00Z", + "value": 11020 + }, + { + "date": "2022-02-05T00:00:00Z", + "value": 11020 + }, + { + "date": "2022-02-06T00:00:00Z", + "value": 11020 + }, + { + "date": "2022-02-07T00:00:00Z", + "value": 11020 + } + ], + "savings_total": 11020, + "swr": 4, + "xirr": 1.76, + "yearly_expense": 0 +} \ No newline at end of file diff --git a/tests/fixture/eur/transaction.json b/tests/fixture/eur/transaction.json new file mode 100644 index 00000000..c2590dd7 --- /dev/null +++ b/tests/fixture/eur/transaction.json @@ -0,0 +1,100 @@ +{ + "transactions": [ + { + "id": "2", + "date": "2022-01-05T00:00:00Z", + "payee": "Buy stock", + "postings": [ + { + "id": 3, + "transaction_id": "2", + "date": "2022-01-05T00:00:00Z", + "payee": "Buy stock", + "account": "Assets:Equity:AAPL", + "commodity": "AAPL", + "quantity": 1, + "amount": 10005.05, + "status": "unmarked", + "tag_recurring": "", + "tag_period": "", + "transaction_begin_line": 11, + "transaction_end_line": 14, + "file_name": "main.ledger", + "forecast": false, + "market_amount": 0 + }, + { + "id": 4, + "transaction_id": "2", + "date": "2022-01-05T00:00:00Z", + "payee": "Buy stock", + "account": "Assets:Checking", + "commodity": "EUR", + "quantity": -10005.05, + "amount": -10005.05, + "status": "unmarked", + "tag_recurring": "", + "tag_period": "", + "transaction_begin_line": 11, + "transaction_end_line": 14, + "file_name": "main.ledger", + "forecast": false, + "market_amount": 0 + } + ], + "tag_recurring": "", + "tag_period": "", + "beginLine": 11, + "endLine": 14, + "fileName": "main.ledger" + }, + { + "id": "1", + "date": "2022-01-01T00:00:00Z", + "payee": "Salary", + "postings": [ + { + "id": 2, + "transaction_id": "1", + "date": "2022-01-01T00:00:00Z", + "payee": "Salary", + "account": "Assets:Checking", + "commodity": "EUR", + "quantity": 11000, + "amount": 11000, + "status": "unmarked", + "tag_recurring": "", + "tag_period": "", + "transaction_begin_line": 4, + "transaction_end_line": 7, + "file_name": "main.ledger", + "forecast": false, + "market_amount": 0 + }, + { + "id": 1, + "transaction_id": "1", + "date": "2022-01-01T00:00:00Z", + "payee": "Salary", + "account": "Income:Salary:Acme", + "commodity": "EUR", + "quantity": -11000, + "amount": -11000, + "status": "unmarked", + "tag_recurring": "", + "tag_period": "", + "transaction_begin_line": 4, + "transaction_end_line": 7, + "file_name": "main.ledger", + "forecast": false, + "market_amount": 0 + } + ], + "tag_recurring": "", + "tag_period": "", + "beginLine": 4, + "endLine": 7, + "fileName": "main.ledger" + } + ] +} \ No newline at end of file