fix: aregister: Make multicommodity amounts are properly aligned in

aregister. (#1656)

This also switches to the renderTable interface for laying out
aregister, just as in postingsReport.
This commit is contained in:
Stephen Morgan 2021-08-19 13:20:24 +10:00 committed by Simon Michael
parent 06312c353a
commit 59b89947eb
2 changed files with 51 additions and 35 deletions

View File

@ -19,17 +19,19 @@ module Hledger.Cli.Commands.Aregister (
,tests_Aregister ,tests_Aregister
) where ) where
import Data.List (find, intersperse) import Data.Default (def)
import Data.List (find)
import Data.Maybe (fromMaybe) import Data.Maybe (fromMaybe)
import qualified Data.Text as T import qualified Data.Text as T
import qualified Data.Text.Lazy as TL import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.Builder as TB import qualified Data.Text.Lazy.Builder as TB
import System.Console.CmdArgs.Explicit (flagNone, flagReq) import System.Console.CmdArgs.Explicit (flagNone, flagReq)
import Hledger.Read.CsvReader (CSV, CsvRecord, printCSV)
import Hledger import Hledger
import Hledger.Read.CsvReader (CSV, CsvRecord, printCSV)
import Hledger.Cli.CliOptions import Hledger.Cli.CliOptions
import Hledger.Cli.Utils import Hledger.Cli.Utils
import Text.Tabular.AsciiWide
aregistermode = hledgerCommandMode aregistermode = hledgerCommandMode
$(embedFileRelative "Hledger/Cli/Commands/Aregister.txt") $(embedFileRelative "Hledger/Cli/Commands/Aregister.txt")
@ -123,17 +125,16 @@ accountTransactionsReportItemAsCsvRecord
-- | Render a register report as plain text suitable for console output. -- | Render a register report as plain text suitable for console output.
accountTransactionsReportAsText :: CliOpts -> Query -> Query -> AccountTransactionsReport -> TL.Text accountTransactionsReportAsText :: CliOpts -> Query -> Query -> AccountTransactionsReport -> TL.Text
accountTransactionsReportAsText copts reportq thisacctq items accountTransactionsReportAsText copts reportq thisacctq items = TB.toLazyText $
= TB.toLazyText . unlinesB $ title <> TB.singleton '\n' <> lines
title :
map (accountTransactionsReportItemAsText copts reportq thisacctq amtwidth balwidth) items
where where
amtwidth = maximumStrict $ 12 : map (wbWidth . showamt . itemamt) items lines = foldMap (accountTransactionsReportItemAsText copts reportq thisacctq amtwidth balwidth) items
balwidth = maximumStrict $ 12 : map (wbWidth . showamt . itembal) items amtwidth = maximumStrict $ 12 : widths (map itemamt items)
showamt = showMixedAmountB oneLine{displayMinWidth=Just 12, displayMaxWidth=mmax} -- color_ balwidth = maximumStrict $ 12 : widths (map itembal items)
where mmax = if no_elide_ . _rsReportOpts . reportspec_ $ copts then Nothing else Just 32 widths = map wbWidth . concatMap (showMixedAmountLinesB oneLine)
itemamt (_,_,_,_,a,_) = a itemamt (_,_,_,_,a,_) = a
itembal (_,_,_,_,_,a) = a itembal (_,_,_,_,_,a) = a
-- show a title indicating which account was picked, which can be confusing otherwise -- show a title indicating which account was picked, which can be confusing otherwise
title = maybe mempty (\s -> foldMap TB.fromText ["Transactions in ", s, " and subaccounts:"]) macct title = maybe mempty (\s -> foldMap TB.fromText ["Transactions in ", s, " and subaccounts:"]) macct
where where
@ -165,20 +166,23 @@ accountTransactionsReportItemAsText
-- String -- a display string describing the other account(s), if any -- String -- a display string describing the other account(s), if any
-- MixedAmount -- the amount posted to the current account(s) (or total amount posted) -- MixedAmount -- the amount posted to the current account(s) (or total amount posted)
-- MixedAmount -- the register's running total or the current account(s)'s historical balance, after this transaction -- MixedAmount -- the register's running total or the current account(s)'s historical balance, after this transaction
foldMap TB.fromText . concat . intersperse (["\n"]) $ table <> TB.singleton '\n'
[ fitText (Just datewidth) (Just datewidth) True True date
, " "
, fitText (Just descwidth) (Just descwidth) True True tdescription
, " "
, fitText (Just acctwidth) (Just acctwidth) True True accts
, " "
, amtfirstline
, " "
, balfirstline
]
:
[ [ spacer, a, " ", b ] | (a,b) <- zip amtrest balrest ]
where where
table = renderRowB def{tableBorders=False, borderSpaces=False} . Group NoLine $ map Header
[ textCell TopLeft $ fitText (Just datewidth) (Just datewidth) True True date
, spacerCell
, textCell TopLeft $ fitText (Just descwidth) (Just descwidth) True True tdescription
, spacerCell2
, textCell TopLeft $ fitText (Just acctwidth) (Just acctwidth) True True accts
, spacerCell2
, Cell TopRight $ map (pad amtwidth) amt
, spacerCell2
, Cell BottomRight $ map (pad balwidth) bal
]
spacerCell = Cell BottomLeft [WideBuilder (TB.singleton ' ') 1]
spacerCell2 = Cell BottomLeft [WideBuilder (TB.fromString " ") 2]
pad fullwidth amt = WideBuilder (TB.fromText $ T.replicate w " ") w <> amt
where w = fullwidth - wbWidth amt
-- calculate widths -- calculate widths
(totalwidth,mdescwidth) = registerWidthsFromOpts copts (totalwidth,mdescwidth) = registerWidthsFromOpts copts
(datewidth, date) = (10, showDate $ transactionRegisterDate reportq thisacctq t) (datewidth, date) = (10, showDate $ transactionRegisterDate reportq thisacctq t)
@ -200,18 +204,9 @@ accountTransactionsReportItemAsText
-- gather content -- gather content
accts = -- T.unpack $ elideAccountName acctwidth $ T.pack accts = -- T.unpack $ elideAccountName acctwidth $ T.pack
otheracctsstr otheracctsstr
amt = TL.toStrict . TB.toLazyText . wbBuilder $ showamt amtwidth change amt = showamt change
bal = TL.toStrict . TB.toLazyText . wbBuilder $ showamt balwidth balance bal = showamt balance
showamt w = showMixedAmountB noPrice{displayColour=color_, displayMinWidth=Just w, displayMaxWidth=Just w} showamt = showMixedAmountLinesB noPrice{displayColour=color_}
-- alternate behaviour, show null amounts as 0 instead of blank
-- amt = if null amt' then "0" else amt'
-- bal = if null bal' then "0" else bal'
(amtlines, ballines) = (T.lines amt, T.lines bal)
(amtlen, ballen) = (length amtlines, length ballines)
numlines = max 1 (max amtlen ballen)
(amtfirstline:amtrest) = take numlines $ amtlines ++ repeat "" -- posting amount is top-aligned
(balfirstline:balrest) = take numlines $ replicate (numlines - ballen) "" ++ ballines -- balance amount is bottom-aligned
spacer = T.replicate (totalwidth - (amtwidth + 2 + balwidth)) " "
-- tests -- tests

View File

@ -79,3 +79,24 @@ Transactions in a and subaccounts:
2021-01-03 fifth a 5 15 2021-01-03 fifth a 5 15
2021-01-03 sixth, because fo.. a 6 21 2021-01-03 sixth, because fo.. a 6 21
2021-01-04 seventh, because .. b 7 28 2021-01-04 seventh, because .. b 7 28
<
2021-01-01
a 1 A
a -1 B
b 1 B
c -1 A
2021-01-02
a 1 C
b -1 C
# 6. aregister correctly aligns amounts when there are multiple commodities (#1656).
$ hledger -f- areg a
Transactions in a and subaccounts:
2021-01-01 b, c 1 A 1 A
-1 B -1 B
2021-01-02 b 1 C 1 A
-1 B
1 C