cli: Commands.Register.postingsReportItemAsRecord: export amounts as number plus commodity

lib: Write.Spreadsheet.cellFromMixedAmount, cellsFromMixedAmount: taken from Cli.Balance
This commit is contained in:
Henning Thielemann 2024-10-17 12:58:13 +02:00 committed by Simon Michael
parent d7b713f958
commit b23753f5ae
3 changed files with 60 additions and 44 deletions

View File

@ -22,12 +22,18 @@ module Hledger.Write.Spreadsheet (
addHeaderBorders,
addRowSpanHeader,
rawTableContent,
cellFromMixedAmount,
cellsFromMixedAmount,
) where
import Hledger.Data.Types (Amount)
import qualified Hledger.Data.Amount as Amt
import Hledger.Data.Types (Amount, MixedAmount, acommodity)
import Hledger.Data.Amount (AmountFormat)
import qualified Data.List as List
import qualified Data.Text as Text
import Data.Text (Text)
import Text.WideString (WideBuilder)
import Prelude hiding (span)
@ -201,3 +207,36 @@ addRowSpanHeader header rows =
rawTableContent :: [[Cell border text]] -> [[text]]
rawTableContent = map (map cellContent)
cellFromMixedAmount ::
(Lines border) =>
AmountFormat -> (Class, MixedAmount) -> Cell border WideBuilder
cellFromMixedAmount bopts (cls, mixedAmt) =
(defaultCell $ Amt.showMixedAmountB bopts mixedAmt) {
cellClass = cls,
cellType =
case Amt.unifyMixedAmount mixedAmt of
Just amt -> amountType bopts amt
Nothing -> TypeMixedAmount
}
cellsFromMixedAmount ::
(Lines border) =>
AmountFormat -> (Class, MixedAmount) -> [Cell border WideBuilder]
cellsFromMixedAmount bopts (cls, mixedAmt) =
map
(\(str,amt) ->
(defaultCell str) {
cellClass = cls,
cellType = amountType bopts amt
})
(Amt.showMixedAmountLinesPartsB bopts mixedAmt)
amountType :: AmountFormat -> Amount -> Type
amountType bopts amt =
TypeAmount $
if Amt.displayCommodity bopts
then amt
else amt {acommodity = Text.empty}

View File

@ -308,7 +308,9 @@ import Hledger.Cli.Utils
import Hledger.Write.Csv (CSV, printCSV, printTSV)
import Hledger.Write.Ods (printFods)
import Hledger.Write.Html.Lucid (printHtml)
import Hledger.Write.Spreadsheet (rawTableContent, addHeaderBorders, addRowSpanHeader, headerCell)
import Hledger.Write.Spreadsheet (rawTableContent, headerCell,
addHeaderBorders, addRowSpanHeader,
cellFromMixedAmount, cellsFromMixedAmount)
import qualified Hledger.Write.Spreadsheet as Ods
@ -710,37 +712,6 @@ balanceReportAsSpreadsheet opts (items, total) =
| layout_ opts == LayoutBare = (False, Just $ S.toList $ maCommodities mixedAmt)
| otherwise = (True, Nothing)
cellFromMixedAmount ::
(Ods.Lines border) =>
AmountFormat -> (Ods.Class, MixedAmount) -> Ods.Cell border WideBuilder
cellFromMixedAmount bopts (cls, mixedAmt) =
(Ods.defaultCell $ showMixedAmountB bopts mixedAmt) {
Ods.cellClass = cls,
Ods.cellType =
case unifyMixedAmount mixedAmt of
Just amt -> amountType bopts amt
Nothing -> Ods.TypeMixedAmount
}
cellsFromMixedAmount ::
(Ods.Lines border) =>
AmountFormat -> (Ods.Class, MixedAmount) -> [Ods.Cell border WideBuilder]
cellsFromMixedAmount bopts (cls, mixedAmt) =
map
(\(str,amt) ->
(Ods.defaultCell str) {
Ods.cellClass = cls,
Ods.cellType = amountType bopts amt
})
(showMixedAmountLinesPartsB bopts mixedAmt)
amountType :: AmountFormat -> Amount -> Ods.Type
amountType bopts amt =
Ods.TypeAmount $
if displayCommodity bopts
then amt
else amt {acommodity = T.empty}
-- Multi-column balance reports

View File

@ -101,31 +101,37 @@ register opts@CliOpts{rawopts_=rawopts, reportspec_=rspec} j
| fmt=="tsv" = printTSV . postingsReportAsCsv
| fmt=="html" =
(<>"\n") . Lucid.renderText . printHtml .
map (map (fmap Lucid.toHtml)) . postingsReportAsSpreadsheet
map (map (fmap Lucid.toHtml)) .
postingsReportAsSpreadsheet oneLineNoCostFmt
| fmt=="fods" =
printFods IO.localeEncoding . Map.singleton "Register" .
(,) (Just 1, Nothing) . postingsReportAsSpreadsheet
(,) (Just 1, Nothing) .
postingsReportAsSpreadsheet oneLineNoCostFmt
| otherwise = error' $ unsupportedOutputFormatError fmt -- PARTIAL:
where fmt = outputFormatFromOpts opts
postingsReportAsCsv :: PostingsReport -> CSV
postingsReportAsCsv = Spr.rawTableContent . postingsReportAsSpreadsheet
postingsReportAsCsv =
Spr.rawTableContent . postingsReportAsSpreadsheet machineFmt
postingsReportAsSpreadsheet ::
PostingsReport -> [[Spr.Cell Spr.NumLines T.Text]]
postingsReportAsSpreadsheet is =
AmountFormat -> PostingsReport -> [[Spr.Cell Spr.NumLines T.Text]]
postingsReportAsSpreadsheet fmt is =
Spr.addHeaderBorders
(map Spr.headerCell
["txnidx","date","code","description","account","amount","total"])
:
map postingsReportItemAsRecord is
map (postingsReportItemAsRecord fmt) is
postingsReportItemAsRecord ::
(Spr.Lines border) => PostingsReportItem -> [Spr.Cell border T.Text]
postingsReportItemAsRecord (_, _, _, p, b) =
(Spr.Lines border) =>
AmountFormat -> PostingsReportItem -> [Spr.Cell border T.Text]
postingsReportItemAsRecord fmt (_, _, _, p, b) =
[cell idx,
(cell date) {Spr.cellType = Spr.TypeDate},
cell code, cell desc, cell acct, cell amt, cell bal]
cell code, cell desc, cell acct,
amountCell (pamount p),
amountCell b]
where
cell = Spr.defaultCell
idx = T.pack . show . maybe 0 tindex $ ptransaction p
@ -139,8 +145,8 @@ postingsReportItemAsRecord (_, _, _, p, b) =
VirtualPosting -> wrap "(" ")"
_ -> id
-- Since postingsReport strips prices from all Amounts when not used, we can display prices.
amt = wbToText . showMixedAmountB machineFmt $ pamount p
bal = wbToText $ showMixedAmountB machineFmt b
amountCell amt =
wbToText <$> Spr.cellFromMixedAmount fmt (Spr.Class "amount", amt)
-- | Render a register report as plain text suitable for console output.
postingsReportAsText :: CliOpts -> PostingsReport -> TL.Text