Show negative values as parentheses on Accounts
This commit is contained in:
@@ -42,7 +42,11 @@ module Hledger
|
||||
rows, total = parse_json(result.stdout)
|
||||
|
||||
sections = [
|
||||
{ "title" => nil, "rows" => account_rows(Array(rows)), "total" => amounts(Array(total)) },
|
||||
{
|
||||
"title" => nil,
|
||||
"rows" => account_rows(Array(rows)),
|
||||
"total" => amounts(Array(total), parenthesize: true),
|
||||
},
|
||||
]
|
||||
|
||||
envelope("accounts", begin_date, end_date, "sections" => sections, "net" => nil)
|
||||
@@ -176,7 +180,7 @@ module Hledger
|
||||
[(full || display).to_s, Array(row_amounts).map { |amount| raw_amount(amount) }]
|
||||
end
|
||||
|
||||
tree_rows(entries)
|
||||
tree_rows(entries, parenthesize: true)
|
||||
end
|
||||
|
||||
def compound_rows(rows)
|
||||
@@ -204,11 +208,13 @@ module Hledger
|
||||
end
|
||||
end
|
||||
|
||||
def tree_rows(entries)
|
||||
def tree_rows(entries, parenthesize: false)
|
||||
AccountTree
|
||||
.expand(entries)
|
||||
.map do |node|
|
||||
node.merge("amounts" => node["amounts"].map { |part| normalized_amount(part) })
|
||||
node.merge(
|
||||
"amounts" => node["amounts"].map { |part| normalized_amount(part, parenthesize:) },
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -216,8 +222,8 @@ module Hledger
|
||||
label.to_s.casecmp?(title.to_s)
|
||||
end
|
||||
|
||||
def amounts(list)
|
||||
Array(list).map { |amount| normalized_amount(raw_amount(amount)) }
|
||||
def amounts(list, parenthesize: false)
|
||||
Array(list).map { |amount| normalized_amount(raw_amount(amount), parenthesize:) }
|
||||
end
|
||||
|
||||
def raw_amount(amount)
|
||||
@@ -228,7 +234,7 @@ module Hledger
|
||||
}
|
||||
end
|
||||
|
||||
def normalized_amount(part)
|
||||
def normalized_amount(part, parenthesize: false)
|
||||
commodity = part["commodity"].to_s
|
||||
quantity = part["quantity"]
|
||||
style = part["style"] || {}
|
||||
@@ -236,7 +242,7 @@ module Hledger
|
||||
{
|
||||
"commodity" => commodity,
|
||||
"quantity" => quantity.to_s("F"),
|
||||
"display" => display_amount(quantity, commodity, style),
|
||||
"display" => display_amount(quantity, commodity, style, parenthesize:),
|
||||
"side" => style["ascommodityside"] || "R",
|
||||
"spaced" => style["ascommodityspaced"] ? true : false,
|
||||
"precision" => style["asprecision"],
|
||||
@@ -251,25 +257,31 @@ module Hledger
|
||||
BigDecimal(mantissa) / (10**places)
|
||||
end
|
||||
|
||||
def display_amount(quantity, commodity, style)
|
||||
def display_amount(quantity, commodity, style, parenthesize: false)
|
||||
precision = style["asprecision"]
|
||||
if precision.nil?
|
||||
rendered = quantity.to_s("F")
|
||||
rendered = quantity.abs.to_s("F")
|
||||
precision = rendered.include?(".") ? rendered.split(".").last.length : 0
|
||||
end
|
||||
mark = style["asdecimalmark"].presence || "."
|
||||
|
||||
number = format("%.#{precision}f", quantity)
|
||||
magnitude = parenthesize ? quantity.abs : quantity
|
||||
number = format("%.#{precision}f", magnitude)
|
||||
number = number.tr(".", mark) if mark != "."
|
||||
|
||||
return number if commodity.blank?
|
||||
text =
|
||||
if commodity.blank?
|
||||
number
|
||||
else
|
||||
spaced = style["ascommodityspaced"] ? " " : ""
|
||||
if style["ascommodityside"] == "L"
|
||||
"#{commodity}#{spaced}#{number}"
|
||||
else
|
||||
"#{number}#{spaced}#{commodity}"
|
||||
end
|
||||
end
|
||||
|
||||
spaced = style["ascommodityspaced"] ? " " : ""
|
||||
if style["ascommodityside"] == "L"
|
||||
"#{commodity}#{spaced}#{number}"
|
||||
else
|
||||
"#{number}#{spaced}#{commodity}"
|
||||
end
|
||||
parenthesize && quantity.negative? ? "(#{text})" : text
|
||||
end
|
||||
|
||||
def balance_flags(begin_date, end_date)
|
||||
|
||||
@@ -40,6 +40,7 @@ RSpec.describe "Hledger integration" do
|
||||
expect(by_account.keys.first(3)).to eq(%w[assets assets:bank assets:bank:checking])
|
||||
expect(by_account["assets:bank"]["label"]).to eq("Bank")
|
||||
expect(by_account["assets:bank"]["amounts"].first["display"]).to eq("1029.50 EUR")
|
||||
expect(by_account["equity:alice"]["amounts"].first["display"]).to eq("(600.00 EUR)")
|
||||
end
|
||||
|
||||
it "renders the balance sheet and income statement as trees" do
|
||||
|
||||
@@ -63,7 +63,8 @@ RSpec.describe Hledger::ReportBuilder do
|
||||
expect(assets["amounts"].first["display"]).to eq("1029.50 EUR")
|
||||
|
||||
equity = rows.find { |row| row["account"] == "equity" }
|
||||
expect(equity["amounts"].first["display"]).to eq("-1000.00 EUR")
|
||||
expect(equity["amounts"].first["display"]).to eq("(1000.00 EUR)")
|
||||
expect(equity["amounts"].first["quantity"]).to eq("-1000.0")
|
||||
|
||||
checking = rows.find { |row| row["account"] == "assets:bank:checking" }
|
||||
expect(checking["depth"]).to eq(2)
|
||||
|
||||
@@ -40,6 +40,15 @@ const accountsReport = {
|
||||
{ commodity: "EUR", quantity: "1000.0", display: "1000.00 EUR" },
|
||||
],
|
||||
},
|
||||
{
|
||||
account: "equity",
|
||||
label: "Equity",
|
||||
depth: 0,
|
||||
root: true,
|
||||
amounts: [
|
||||
{ commodity: "EUR", quantity: "-1000.0", display: "(1000.00 EUR)" },
|
||||
],
|
||||
},
|
||||
],
|
||||
total: [{ commodity: "EUR", quantity: "1000.0", display: "1000.00 EUR" }],
|
||||
},
|
||||
@@ -279,6 +288,9 @@ acceptance("Hledger plugin", function (needs) {
|
||||
assert.dom(".hledger-dashboard__table").includesText("Bank");
|
||||
assert.dom(".hledger-dashboard__table").includesText("Checking");
|
||||
assert.dom(".hledger-dashboard__table").includesText("1000.00 EUR");
|
||||
assert
|
||||
.dom(".hledger-dashboard__table")
|
||||
.includesText("(1000.00 EUR)", "shows credit balances in parentheses");
|
||||
assert.dom(".hledger-dashboard__account.--depth-1").hasText("Bank");
|
||||
assert.dom(".hledger-dashboard__account.--depth-2").hasText("Checking");
|
||||
assert
|
||||
|
||||
Reference in New Issue
Block a user