@@ -641,6 +641,9 @@ headerDateSpanCell base query spn =
641641 Ods. cellAnchor = composeAnchor base $ replaceDate prd query
642642 }
643643
644+ headerWithoutBorders :: [Ods. Cell () text ] -> [Ods. Cell Ods. NumLines text ]
645+ headerWithoutBorders = map (\ c -> c {Ods. cellBorder = Ods. noBorder})
646+
644647addHeaderBorders :: [Ods. Cell () text ] -> [Ods. Cell Ods. NumLines text ]
645648addHeaderBorders =
646649 map (\ c -> c {Ods. cellBorder =
@@ -689,8 +692,11 @@ balanceReportAsSpreadsheet opts (items, total) =
689692 headers =
690693 addHeaderBorders $ map headerCell $
691694 " account" : case layout_ opts of
695+ LayoutBareWide -> allCommodities
692696 LayoutBare -> [" commodity" , " balance" ]
693697 _ -> [" balance" ]
698+ allCommodities =
699+ S. toAscList $ foldMap (\ (_,_,_,ma) -> maCommodities ma) items
694700 rows ::
695701 RowClass -> BalanceReportItem ->
696702 [[Ods. Cell Ods. NumLines Text ]]
@@ -702,6 +708,15 @@ balanceReportAsSpreadsheet opts (items, total) =
702708 cell $ renderBalanceAcct opts nbsp (name, dispName, dep) in
703709 addRowSpanHeader accountCell $
704710 case layout_ opts of
711+ LayoutBareWide ->
712+ let bopts =
713+ machineFmt {
714+ displayCommodity = False ,
715+ displayCommodityOrder = Just allCommodities
716+ } in
717+ [map (\ bldAmt ->
718+ fmap wbToText $ cellFromAmount bopts (amountClass rc, bldAmt)) $
719+ showMixedAmountLinesPartsB bopts ma]
705720 LayoutBare ->
706721 map (\ a -> [cell $ acommodity a, renderAmount rc $ mixedAmount a])
707722 . amounts $ mixedAmountStripCosts ma
@@ -739,6 +754,15 @@ cellsFromMixedAmount bopts (cls, mixedAmt) =
739754 })
740755 (showMixedAmountLinesPartsB bopts mixedAmt)
741756
757+ cellFromAmount ::
758+ (Ods. Lines border ) =>
759+ AmountFormat -> (Ods. Class , (wb , Amount )) -> Ods. Cell border wb
760+ cellFromAmount bopts (cls, (str,amt)) =
761+ (Ods. defaultCell str) {
762+ Ods. cellClass = cls,
763+ Ods. cellType = amountType bopts amt
764+ }
765+
742766amountType :: AmountFormat -> Amount -> Ods. Type
743767amountType bopts amt =
744768 Ods. TypeAmount $
@@ -756,29 +780,41 @@ amountType bopts amt =
756780multiBalanceReportAsCsv :: ReportOpts -> MultiBalanceReport -> CSV
757781multiBalanceReportAsCsv opts@ ReportOpts {.. } report =
758782 (if transpose_ then transpose else id ) $
759- rawTableContent $ header : body ++ totals
783+ rawTableContent $ header ++ body ++ totals
760784 where
761785 (header, body, totals) =
762- multiBalanceReportAsSpreadsheetParts machineFmt opts report
786+ multiBalanceReportAsSpreadsheetParts machineFmt opts
787+ (allCommoditiesFromPeriodicReport $ prRows report) report
763788
764789-- | Render the Spreadsheet table rows (CSV, ODS, HTML) for a MultiBalanceReport.
765790-- Returns the heading row, 0 or more body rows, and the totals row if enabled.
766791multiBalanceReportAsSpreadsheetParts ::
767- AmountFormat -> ReportOpts -> MultiBalanceReport ->
768- ([Ods. Cell Ods. NumLines Text ],
792+ AmountFormat -> ReportOpts ->
793+ [CommoditySymbol ] -> MultiBalanceReport ->
794+ ([[Ods. Cell Ods. NumLines Text ]],
769795 [[Ods. Cell Ods. NumLines Text ]],
770796 [[Ods. Cell Ods. NumLines Text ]])
771- multiBalanceReportAsSpreadsheetParts fmt opts@ ReportOpts {.. } (PeriodicReport colspans items tr) =
772- (headers, concatMap fullRowAsTexts items, addTotalBorders totalrows)
797+ multiBalanceReportAsSpreadsheetParts fmt opts@ ReportOpts {.. }
798+ allCommodities (PeriodicReport colspans items tr) =
799+ (allHeaders, concatMap fullRowAsTexts items, addTotalBorders totalrows)
773800 where
774801 accountCell label =
775802 (Ods. defaultCell label) {Ods. cellClass = Ods. Class " account" }
776803 hCell cls label = (headerCell label) {Ods. cellClass = Ods. Class cls}
804+ allHeaders =
805+ case layout_ of
806+ LayoutBareWide ->
807+ [headerWithoutBorders $
808+ Ods. emptyCell :
809+ concatMap (Ods. horizontalSpan allCommodities) dateHeaders,
810+ headers]
811+ _ -> [headers]
777812 headers =
778813 addHeaderBorders $
779814 hCell " account" " account" :
780815 case layout_ of
781816 LayoutTidy -> map headerCell tidyColumnLabels
817+ LayoutBareWide -> dateHeaders >> map headerCell allCommodities
782818 LayoutBare -> headerCell " commodity" : dateHeaders
783819 _ -> dateHeaders
784820 dateHeaders =
@@ -799,7 +835,7 @@ multiBalanceReportAsSpreadsheetParts fmt opts@ReportOpts{..} (PeriodicReport col
799835 rowAsText Total simpleDateSpanCell tr
800836 rowAsText rc dsCell =
801837 map (map (fmap wbToText)) .
802- multiBalanceRowAsCellBuilders fmt opts colspans rc dsCell
838+ multiBalanceRowAsCellBuilders fmt opts colspans allCommodities rc dsCell
803839
804840tidyColumnLabels :: [Text ]
805841tidyColumnLabels =
@@ -819,10 +855,12 @@ multiBalanceReportAsSpreadsheet ::
819855 ((Maybe Int , Maybe Int ), [[Ods. Cell Ods. NumLines Text ]])
820856multiBalanceReportAsSpreadsheet ropts mbr =
821857 let (header,body,total) =
822- multiBalanceReportAsSpreadsheetParts oneLineNoCostFmt ropts mbr
858+ multiBalanceReportAsSpreadsheetParts oneLineNoCostFmt ropts
859+ (allCommoditiesFromPeriodicReport $ prRows mbr) mbr
823860 in (if transpose_ ropts then swap *** Ods. transpose else id ) $
824- ((Just 1 , case layout_ ropts of LayoutWide _ -> Just 1 ; _ -> Nothing ),
825- header : body ++ total)
861+ ((Just $ case layout_ ropts of LayoutBareWide -> 2 ; _ -> 1 ,
862+ case layout_ ropts of LayoutWide _ -> Just 1 ; _ -> Nothing ),
863+ header ++ body ++ total)
826864
827865
828866-- | Render a multi-column balance report as plain text suitable for console output.
@@ -893,19 +931,24 @@ multiBalanceReportAsTable opts@ReportOpts{summary_only_, average_, balanceaccum_
893931 (concat rows)
894932 where
895933 colheadings = [" Commodity" | layout_ opts == LayoutBare ]
896- ++ (if not summary_only_ then map (reportPeriodName balanceaccum_ spans) spans else [] )
934+ ++ (if not summary_only_
935+ then case layout_ opts of
936+ LayoutBareWide -> spans >> allCommodities
937+ _ -> map (reportPeriodName balanceaccum_ spans) spans
938+ else [] )
897939 ++ [" Total" | multiBalanceHasTotalsColumn opts]
898940 ++ [" Average" | average_]
941+ allCommodities = allCommoditiesFromPeriodicReport items
899942 (accts, rows) = unzip $ fmap fullRowAsTexts items
900943 where
901944 fullRowAsTexts row = (replicate (length rs) (renderacct row), rs)
902945 where
903- rs = multiBalanceRowAsText opts row
946+ rs = multiBalanceRowAsText opts allCommodities row
904947 renderacct row' = T. replicate (prrIndent row' * 2 ) " " <> prrDisplayName row'
905948 addtotalrow
906949 | no_total_ opts = id
907950 | otherwise =
908- let totalrows = multiBalanceRowAsText opts tr
951+ let totalrows = multiBalanceRowAsText opts allCommodities tr
909952 rowhdrs = Group NoLine $ map Header $ totalRowHeadingText : replicate (length totalrows - 1 ) " "
910953 colhdrs = Header [] -- unused, concatTables will discard
911954 in (flip (concatTables SingleLine ) $ Table rowhdrs colhdrs totalrows)
@@ -914,12 +957,17 @@ multiBalanceReportAsTable opts@ReportOpts{summary_only_, average_, balanceaccum_
914957 multiColumnTableInterRowBorder = NoLine
915958 multiColumnTableInterColumnBorder = if pretty_ opts then SingleLine else NoLine
916959
960+ allCommoditiesFromPeriodicReport ::
961+ [PeriodicReportRow a MixedAmount ] -> [CommoditySymbol ]
962+ allCommoditiesFromPeriodicReport =
963+ S. toAscList . foldMap (foldMap maCommodities . prrAmounts)
964+
917965multiBalanceRowAsCellBuilders ::
918- AmountFormat -> ReportOpts -> [DateSpan ] ->
966+ AmountFormat -> ReportOpts -> [DateSpan ] -> [ CommoditySymbol ] ->
919967 RowClass -> (DateSpan -> Ods. Cell Ods. NumLines Text ) ->
920968 PeriodicReportRow a MixedAmount ->
921969 [[Ods. Cell Ods. NumLines WideBuilder ]]
922- multiBalanceRowAsCellBuilders bopts ropts@ ReportOpts {.. } colspans
970+ multiBalanceRowAsCellBuilders bopts ropts@ ReportOpts {.. } colspans allCommodities
923971 rc renderDateSpanCell (PeriodicReportRow _acct as rowtot rowavg) =
924972 case layout_ of
925973 LayoutWide width -> [fmap (cellFromMixedAmount bopts{displayMaxWidth= width}) clsamts]
@@ -930,6 +978,8 @@ multiBalanceRowAsCellBuilders bopts ropts@ReportOpts{..} colspans
930978 . transpose -- each row becomes a list of Text quantities
931979 . map (cellsFromMixedAmount bopts{displayCommodity= False , displayCommodityOrder= Just cs, displayMinWidth= Nothing })
932980 $ clsamts
981+ LayoutBareWide -> [concatMap (cellsFromMixedAmount bopts{displayCommodity= False , displayCommodityOrder= Just allCommodities, displayMinWidth= Nothing })
982+ $ clsamts]
933983 LayoutTidy -> concat
934984 . zipWith (map . addDateColumns) colspans
935985 . map ( zipWith (\ c a -> [wbCell c, a]) cs
@@ -972,16 +1022,20 @@ multiBalanceHasTotalsColumn :: ReportOpts -> Bool
9721022multiBalanceHasTotalsColumn ropts =
9731023 row_total_ ropts && balanceaccum_ ropts `notElem` [Cumulative , Historical ]
9741024
975- multiBalanceRowAsText :: ReportOpts -> PeriodicReportRow a MixedAmount -> [[WideBuilder ]]
976- multiBalanceRowAsText opts =
1025+ multiBalanceRowAsText ::
1026+ ReportOpts -> [CommoditySymbol ] -> PeriodicReportRow a MixedAmount -> [[WideBuilder ]]
1027+ multiBalanceRowAsText opts allCommodities =
9771028 rawTableContent .
978- multiBalanceRowAsCellBuilders oneLineNoCostFmt{displayColour= color_ opts} opts []
1029+ multiBalanceRowAsCellBuilders oneLineNoCostFmt{displayColour= color_ opts}
1030+ opts [] allCommodities
9791031 Value simpleDateSpanCell
9801032
981- multiBalanceRowAsCsvText :: ReportOpts -> [DateSpan ] -> PeriodicReportRow a MixedAmount -> [[T. Text ]]
982- multiBalanceRowAsCsvText opts colspans =
1033+ multiBalanceRowAsCsvText ::
1034+ ReportOpts -> [DateSpan ] -> [CommoditySymbol ] ->
1035+ PeriodicReportRow a MixedAmount -> [[T. Text ]]
1036+ multiBalanceRowAsCsvText opts colspans allCommodities =
9831037 map (map (wbToText . Ods. cellContent)) .
984- multiBalanceRowAsCellBuilders machineFmt opts colspans
1038+ multiBalanceRowAsCellBuilders machineFmt opts colspans allCommodities
9851039 Value simpleDateSpanCell
9861040
9871041
0 commit comments