show unit and unit price in ledger page
since the unit price is reverse calculated from the purchase amount, export high precision number from ledger to avoid mismatch
This commit is contained in:
parent
a63386ea77
commit
44152d530d
|
@ -4,11 +4,12 @@ import (
|
|||
"bytes"
|
||||
"encoding/csv"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/ananthakumaran/paisa/internal/model/posting"
|
||||
)
|
||||
|
||||
|
@ -20,7 +21,7 @@ func Parse(journalPath string) ([]*posting.Posting, error) {
|
|||
log.Fatal(err)
|
||||
}
|
||||
|
||||
command := exec.Command("ledger", "-f", journalPath, "csv", "--csv-format", "%(quoted(date)),%(quoted(payee)),%(quoted(display_account)),%(quoted(commodity(scrub(display_amount)))),%(quoted(quantity(scrub(display_amount)))),%(quoted(to_int(scrub(market(amount,date)))))\n")
|
||||
command := exec.Command("ledger", "-f", journalPath, "csv", "--csv-format", "%(quoted(date)),%(quoted(payee)),%(quoted(display_account)),%(quoted(commodity(scrub(display_amount)))),%(quoted(quantity(scrub(display_amount)))),%(quoted(to_int(scrub(market(amount,date) * 100000))))\n")
|
||||
var output, error bytes.Buffer
|
||||
command.Stdout = &output
|
||||
command.Stderr = &error
|
||||
|
@ -51,6 +52,7 @@ func Parse(journalPath string) ([]*posting.Posting, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
amount = amount / 100000
|
||||
|
||||
posting := posting.Posting{Date: date, Payee: record[1], Account: record[2], Commodity: record[3], Quantity: quantity, Amount: amount}
|
||||
postings = append(postings, &posting)
|
||||
|
|
|
@ -47,25 +47,34 @@ function renderTransactions(postings: Posting[]) {
|
|||
let market = "",
|
||||
change = "",
|
||||
changePercentage = "",
|
||||
changeClass = "";
|
||||
changeClass = "",
|
||||
price = "",
|
||||
units = "";
|
||||
if (p.commodity !== "INR") {
|
||||
market = formatCurrency(p.market_amount);
|
||||
const changeAmount = p.market_amount - p.amount;
|
||||
if (changeAmount > 0) {
|
||||
changeClass = "has-text-success";
|
||||
} else if (changeAmount < 0) {
|
||||
changeClass = "has-text-danger";
|
||||
units = formatFloat(p.quantity, 4);
|
||||
price = formatCurrency(Math.abs(p.amount / p.quantity), 4);
|
||||
const days = dayjs().diff(p.timestamp, "days");
|
||||
if (p.quantity > 0 && days > 0) {
|
||||
market = formatCurrency(p.market_amount);
|
||||
const changeAmount = p.market_amount - p.amount;
|
||||
if (changeAmount > 0) {
|
||||
changeClass = "has-text-success";
|
||||
} else if (changeAmount < 0) {
|
||||
changeClass = "has-text-danger";
|
||||
}
|
||||
const perYear = 365 / days;
|
||||
changePercentage = formatFloat(
|
||||
(changeAmount / p.amount) * 100 * perYear
|
||||
);
|
||||
change = formatCurrency(changeAmount);
|
||||
}
|
||||
const perYear = 365 / dayjs().diff(p.timestamp, "days");
|
||||
changePercentage = formatFloat(
|
||||
(changeAmount / p.amount) * 100 * perYear
|
||||
);
|
||||
change = formatCurrency(changeAmount);
|
||||
}
|
||||
return `
|
||||
<td>${p.timestamp.format("DD MMM YYYY")}</td>
|
||||
<td>${p.account}</td>
|
||||
<td class='has-text-right'>${purchase}</td>
|
||||
<td class='has-text-right'>${units}</td>
|
||||
<td class='has-text-right'>${price}</td>
|
||||
<td class='has-text-right'>${market}</td>
|
||||
<td class='${changeClass} has-text-right'>${change}</td>
|
||||
<td class='${changeClass} has-text-right'>${changePercentage}</td>
|
||||
|
|
|
@ -9,7 +9,7 @@ export interface Posting {
|
|||
payee: string;
|
||||
account: string;
|
||||
commodity: string;
|
||||
quanity: number;
|
||||
quantity: number;
|
||||
amount: number;
|
||||
market_amount: number;
|
||||
|
||||
|
@ -98,12 +98,15 @@ export async function ajax(route: string) {
|
|||
|
||||
const obscure = false;
|
||||
|
||||
export function formatCurrency(value: number) {
|
||||
export function formatCurrency(value: number, precision = 0) {
|
||||
if (obscure) {
|
||||
return "00";
|
||||
}
|
||||
|
||||
return Math.round(value).toLocaleString("hi");
|
||||
return value.toLocaleString("hi", {
|
||||
minimumFractionDigits: precision,
|
||||
maximumFractionDigits: precision
|
||||
});
|
||||
}
|
||||
|
||||
export function formatCurrencyCrude(value: number) {
|
||||
|
|
|
@ -246,22 +246,31 @@
|
|||
</section>
|
||||
<section class="section tab-ledger">
|
||||
<div class="container is-fluid">
|
||||
<nav class="level">
|
||||
<div class="level-left">
|
||||
<div class="level-item">
|
||||
<p class="subtitle is-5">
|
||||
Postings
|
||||
</p>
|
||||
</div>
|
||||
<div class="level-item">
|
||||
<div class="field">
|
||||
<p class="control">
|
||||
<input class="d3-posting-filter input" style="width: 440px" type="text" placeholder="filter account">
|
||||
</p>
|
||||
<div class="columns">
|
||||
<div class="column is-6">
|
||||
<nav class="level">
|
||||
<div class="level-left">
|
||||
<div class="level-item">
|
||||
<p class="subtitle is-5">
|
||||
Postings
|
||||
</p>
|
||||
</div>
|
||||
<div class="level-item">
|
||||
<div class="field">
|
||||
<p class="control">
|
||||
<input class="d3-posting-filter input" style="width: 440px" type="text" placeholder="filter account">
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="column is-6">
|
||||
<p class="subtitle is-5">
|
||||
Holdings
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="columns">
|
||||
<div class="column is-6">
|
||||
<table class="table is-narrow is-fullwidth">
|
||||
|
@ -270,6 +279,8 @@
|
|||
<th>Date</th>
|
||||
<th>Account</th>
|
||||
<th class='has-text-right'>Amount</th>
|
||||
<th class='has-text-right'>Units</th>
|
||||
<th class='has-text-right'>Unit Price</th>
|
||||
<th class='has-text-right'>Market Value</th>
|
||||
<th class='has-text-right'>Change</th>
|
||||
<th class='has-text-right'>CAGR</th>
|
||||
|
|
Loading…
Reference in New Issue