Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 31 additions & 4 deletions hledger/Hledger/Cli/Anchor.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module Hledger.Cli.Anchor (
LinkOpts(..),
defaultLinkOpts,
linkParams,
valueParam,
composeAnchor,
composeAnchorWith,
accountTerm,
Expand Down Expand Up @@ -42,6 +43,7 @@ import Hledger.Utils.IO (error')
import Hledger.Utils.Text (quoteIfSpaced)
import Hledger.Data.Dates (showDateSpan, showDateSpanFull, showDateSpanForQuery, showDate, nulldatespan)
import Hledger.Data.Types (DateSpan(..))
import Hledger.Data.Valuation (ConversionOp(..), ValuationType(..))
import Hledger.Reports.ReportOptions (PeriodTitles(..), BalanceAccumulation(..))


Expand All @@ -57,17 +59,42 @@ data LinkOpts = LinkOpts {
-- ^ Does the report use secondary dates ? Then so must the register.
loIncludesSubs :: Bool,
-- ^ Does the row's figure include subaccounts (inacct:) or not (inacctonly:) ?
loNegated :: Bool
loNegated :: Bool,
-- ^ Are the figures shown with the opposite sign to the register's ?
loValue :: Maybe Text
-- ^ The register's value parameter, for figures converted to cost
-- or to market value (see 'valueParam').
}

defaultLinkOpts :: LinkOpts
defaultLinkOpts = LinkOpts PerPeriod nulldatespan False True False
defaultLinkOpts = LinkOpts PerPeriod nulldatespan False True False Nothing

-- | The query parameters a link carries besides q: the register's
-- accumulation mode, when it is not the register's default.
-- accumulation mode, when it is not the register's default, and how it
-- converts amounts, when the report converts them.
linkParams :: LinkOpts -> [(Text, Text)]
linkParams lo = [("accum", "historical") | loAccum lo == Historical]
linkParams lo =
[("accum", "historical") | loAccum lo == Historical] ++
[("value", v) | Just v <- [loValue lo]]

-- | The value parameter that asks hledger-web's register to convert
-- amounts as a report does, mirroring --value's WHEN[,COMM] syntax:
-- "cost" for -B, "end" for -V, "end,COMM" for -X COMM, "then", "now",
-- or a date for the other valuations. A register converting them the
-- same way ends on the figure a link was clicked on. Cost combined
-- with a valuation has none, and such links open the register as it is.
valueParam :: Maybe ConversionOp -> Maybe ValuationType -> Maybe Text
valueParam conv val =
case (conv == Just ToCost, val) of
(True, Nothing) -> Just "cost"
(True, Just _) -> Nothing
(False, Nothing) -> Nothing
(False, Just vt) -> Just $ case vt of
AtEnd mc -> "end" <> comm mc
AtThen mc -> "then" <> comm mc
AtNow mc -> "now" <> comm mc
AtDate d mc -> showDate d <> comm mc
where comm = maybe "" ("," <>)

-- | The span a figure's register covers: the period, or, for a
-- cumulative figure, the report's start to the period's end.
Expand Down
3 changes: 2 additions & 1 deletion hledger/Hledger/Cli/Commands/Balance.hs
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,8 @@ balanceReportAsSpreadsheetParts fmt opts (items, total) =
setAccountAnchorWith lo
(guard (rc==Value) >> balance_base_url_ opts)
linkquery name $
(\c -> c{Ods.cellClass = accountClass}) $
(\c -> c{Ods.cellClass = case rc of Value -> treeAccountClass opts dep
Total -> accountClass}) $
cell $ case rc of
Total -> dispName -- show the total row heading as is; --drop etc. don't apply (#2688)
Value -> renderBalanceAcct opts nbsp (name, dispName, dep) in
Expand Down
18 changes: 14 additions & 4 deletions hledger/Hledger/Cli/Commands/Balance/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import Text.Tabular.AsciiWide (Header(..), Properties(..), Table(..), concatTabl

import Hledger.Utils.I18n qualified as I18n
import Hledger
import Hledger.Cli.Anchor (LinkOpts(..), dateTerm, removeDates, withLink, setAccountAnchorWith,
import Hledger.Cli.Anchor (LinkOpts(..), valueParam, dateTerm, removeDates, withLink, setAccountAnchorWith,
dateSpanCellWith, totalDateSpanCell, headerDateSpanCell, renderPeriodHeading, amountPhrase)
import Hledger.Write.Spreadsheet (rawTableContent, headerCell,
addHeaderBorders, addRowSpanHeader,
Expand All @@ -28,6 +28,14 @@ import Hledger.Write.Spreadsheet qualified as Ods
accountClass :: Ods.Class
accountClass = Ods.Class "account"

-- | The class of an account cell in a tree-mode report: "account" and
-- its row's depth in the tree, so that a UI can fold the tree by
-- indent, as hledger-web does. In list mode, just "account".
treeAccountClass :: ReportOpts -> Int -> Ods.Class
treeAccountClass opts dep
| accountlistmode_ opts == ALTree = Ods.Class $ "account depth-" <> T.pack (show dep)
| otherwise = accountClass

data RowClass = Value | Total
deriving (Eq, Ord, Enum, Bounded, Show)

Expand Down Expand Up @@ -71,16 +79,17 @@ figuresLink :: ReportOpts -> Bool
figuresLink ropts = balancecalc_ ropts == CalcChange && not (percent_ ropts)

-- | The register link options of a report's rows: its accumulation
-- mode, the span its columns cover, and whether it shows figures with
-- mode, the span its columns cover, whether it shows figures with
-- the sign opposite to the register's (as the compound reports' negated
-- sections do).
-- sections do), and how it converts amounts.
reportLinkOpts :: ReportOpts -> [DateSpan] -> LinkOpts
reportLinkOpts ropts colspans = LinkOpts {
loAccum = balanceaccum_ ropts,
loSpan = spansSpan colspans,
loDate2 = date2_ ropts,
loIncludesSubs = True,
loNegated = normalbalance_ ropts == Just NormallyNegative
loNegated = normalbalance_ ropts == Just NormallyNegative,
loValue = valueParam (conversionop_ ropts) (value_ ropts)
}

-- | The link options of one account's row: whether its figures include
Expand Down Expand Up @@ -324,6 +333,7 @@ balanceSubReportAsSpreadsheetParts fmt opts@ReportOpts{..}
lo = rowLinkOpts opts colspans shownParents acctName
anchorCell =
setAccountAnchorWith lo balance_base_url_ rowquery acctName $
(\c -> c{Ods.cellClass = treeAccountClass opts (prrIndent row)}) $
accountCell $ renderPeriodicAcct opts nbsp row
totalrows =
if no_total_
Expand Down
19 changes: 19 additions & 0 deletions hledger/test/balance/base-url.test
Original file line number Diff line number Diff line change
Expand Up @@ -333,3 +333,22 @@ $ hledger -f- bal -M -O fods --base-url ''
$ hledger -f- bal -M --date2 -O html --base-url ''
> /<a href="register\?q=inacct:assets:bank\+date2:2025-02" title="Show the transactions that make up this amount">/
>= 0

# ** 23. Converting amounts to market value asks the register to
# convert them the same way, so that it ends on the figure clicked.
<
P 2025-01-01 AAPL $100
P 2025-02-01 AAPL $120

2025-01-05 buy
assets:broker 10 AAPL @ $90
assets:bank

$ hledger -f- bal -M -V -O html --base-url '' assets:broker
> /<a href="register\?q=inacct:assets:broker\+date:2025-01\+assets:broker&amp;value=end" title="Show the transactions that make up this amount">/
>= 0

# ** 24. Converting them to cost.
$ hledger -f- bal -M -B -O html --base-url '' assets:broker
> /<a href="register\?q=inacct:assets:broker\+date:2025-01\+assets:broker&amp;value=cost" title="Show the transactions that make up this amount">/
>= 0
18 changes: 18 additions & 0 deletions hledger/test/balance/html.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# * balance html output

# ** 1. In tree mode each account cell's class carries its depth, so a
# stylesheet can indent the tree and a UI can fold it (hledger-web does).
<
2025-01-15 a
assets:bank:checking 10
assets:cash 5
income

$ hledger -f- bal --tree -O html
> /<td class="account depth-1"/
>= 0

# ** 2. In list mode, the default, account cells have no depth.
$ hledger -f- bal -O html
> !/depth-/
>= 0