@@ -584,15 +584,8 @@ renderComponent topaligned oneline opts (acctname, dep, total) (FormatField ljus
584
584
}
585
585
586
586
587
- headerCell :: Text -> Ods. Cell Ods. NumLines Text
588
- headerCell text =
589
- let deflt = Ods. defaultCell text
590
- in
591
- deflt {
592
- Ods. cellStyle = Ods. Head ,
593
- Ods. cellBorder =
594
- (Ods. cellBorder deflt) {Ods. borderBottom = Ods. DoubleLine }
595
- }
587
+ headerCell :: (Ods. Lines borders ) => Text -> Ods. Cell borders Text
588
+ headerCell text = (Ods. defaultCell text) {Ods. cellStyle = Ods. Head }
596
589
597
590
registerQueryUrl :: [Text ] -> Text
598
591
registerQueryUrl query =
@@ -634,13 +627,30 @@ replaceDate :: Text -> [Text] -> [Text]
634
627
replaceDate prd query = " date:" <> prd : removeDates query
635
628
636
629
headerDateSpanCell ::
637
- Maybe Text -> [Text ] -> DateSpan -> Ods. Cell Ods. NumLines Text
630
+ Maybe Text -> [Text ] -> DateSpan -> Ods. Cell () Text
638
631
headerDateSpanCell base query spn =
639
632
let prd = showDateSpan spn in
640
633
(headerCell prd) {
641
634
Ods. cellAnchor = composeAnchor base $ replaceDate prd query
642
635
}
643
636
637
+ headerWithoutBorders :: [Ods. Cell () text ] -> [Ods. Cell Ods. NumLines text ]
638
+ headerWithoutBorders = map (\ c -> c {Ods. cellBorder = Ods. noBorder})
639
+
640
+ addHeaderBorders :: [Ods. Cell () text ] -> [Ods. Cell Ods. NumLines text ]
641
+ addHeaderBorders =
642
+ map (\ c -> c {Ods. cellBorder =
643
+ Ods. noBorder {Ods. borderBottom = Ods. DoubleLine }})
644
+
645
+ groupHeaderCells ::
646
+ (Ods. Lines border , Monoid text ) =>
647
+ [a ] -> Ods. Cell border text -> [Ods. Cell border text ]
648
+ groupHeaderCells subCells cell =
649
+ zipWith const
650
+ (cell{Ods. cellSpan = Ods. SpanHorizontal $ length subCells}
651
+ : repeat (Ods. emptyCell {Ods. cellSpan = Ods. Covered }))
652
+ subCells
653
+
644
654
simpleDateSpanCell :: DateSpan -> Ods. Cell Ods. NumLines Text
645
655
simpleDateSpanCell = Ods. defaultCell . showDateSpan
646
656
@@ -698,10 +708,13 @@ balanceReportAsSpreadsheet opts (items, total) =
698
708
where
699
709
cell = Ods. defaultCell
700
710
headers =
701
- map headerCell $
711
+ addHeaderBorders $ map headerCell $
702
712
" account" : case layout_ opts of
713
+ LayoutBareWide -> allCommodities
703
714
LayoutBare -> [" commodity" , " balance" ]
704
715
_ -> [" balance" ]
716
+ allCommodities =
717
+ S. toAscList $ foldMap (\ (_,_,_,ma) -> maCommodities ma) items
705
718
rows ::
706
719
RowClass -> BalanceReportItem ->
707
720
[[Ods. Cell Ods. NumLines Text ]]
@@ -713,6 +726,15 @@ balanceReportAsSpreadsheet opts (items, total) =
713
726
cell $ renderBalanceAcct opts nbsp (name, dispName, dep) in
714
727
addRowSpanHeader accountCell $
715
728
case layout_ opts of
729
+ LayoutBareWide ->
730
+ let bopts =
731
+ machineFmt {
732
+ displayCommodity = False ,
733
+ displayCommodityOrder = Just allCommodities
734
+ } in
735
+ [map (\ bldAmt ->
736
+ fmap wbToText $ cellFromAmount bopts (amountClass rc, bldAmt)) $
737
+ showMixedAmountLinesPartsB bopts ma]
716
738
LayoutBare ->
717
739
map (\ a -> [cell $ acommodity a, renderAmount rc $ mixedAmount a])
718
740
. amounts $ mixedAmountStripCosts ma
@@ -750,6 +772,15 @@ cellsFromMixedAmount bopts (cls, mixedAmt) =
750
772
})
751
773
(showMixedAmountLinesPartsB bopts mixedAmt)
752
774
775
+ cellFromAmount ::
776
+ (Ods. Lines border ) =>
777
+ AmountFormat -> (Ods. Class , (wb , Amount )) -> Ods. Cell border wb
778
+ cellFromAmount bopts (cls, (str,amt)) =
779
+ (Ods. defaultCell str) {
780
+ Ods. cellClass = cls,
781
+ Ods. cellType = amountType bopts amt
782
+ }
783
+
753
784
amountType :: AmountFormat -> Amount -> Ods. Type
754
785
amountType bopts amt =
755
786
Ods. TypeAmount $
@@ -772,30 +803,43 @@ multiBalanceReportAsCsv opts@ReportOpts{..} report = maybeTranspose allRows
772
803
case layout_ of
773
804
LayoutTidy -> rows -- tidy csv should not include totals or averages
774
805
_ -> rows ++ totals
775
- rows = header: body
806
+ rows = header++ body
776
807
(header, body, totals) =
777
- multiBalanceReportAsSpreadsheetParts machineFmt opts report
808
+ multiBalanceReportAsSpreadsheetParts machineFmt opts
809
+ (allCommoditiesFromPeriodicReport $ prRows report) report
778
810
maybeTranspose = if transpose_ then transpose else id
779
811
780
812
-- | Render the Spreadsheet table rows (CSV, ODS, HTML) for a MultiBalanceReport.
781
813
-- Returns the heading row, 0 or more body rows, and the totals row if enabled.
782
814
multiBalanceReportAsSpreadsheetParts ::
783
- AmountFormat -> ReportOpts -> MultiBalanceReport ->
784
- ([Ods. Cell Ods. NumLines Text ],
815
+ AmountFormat -> ReportOpts ->
816
+ [CommoditySymbol ] -> MultiBalanceReport ->
817
+ ([[Ods. Cell Ods. NumLines Text ]],
785
818
[[Ods. Cell Ods. NumLines Text ]],
786
819
[[Ods. Cell Ods. NumLines Text ]])
787
- multiBalanceReportAsSpreadsheetParts fmt opts@ ReportOpts {.. } (PeriodicReport colspans items tr) =
788
- (headers, concatMap fullRowAsTexts items, addTotalBorders totalrows)
820
+ multiBalanceReportAsSpreadsheetParts fmt opts@ ReportOpts {.. }
821
+ allCommodities (PeriodicReport colspans items tr) =
822
+ (allHeaders, concatMap fullRowAsTexts items, addTotalBorders totalrows)
789
823
where
790
824
accountCell label =
791
825
(Ods. defaultCell label) {Ods. cellClass = Ods. Class " account" }
792
826
hCell cls label = (headerCell label) {Ods. cellClass = Ods. Class cls}
827
+ allHeaders =
828
+ case layout_ of
829
+ LayoutBareWide ->
830
+ [headerWithoutBorders $
831
+ Ods. emptyCell :
832
+ concatMap (groupHeaderCells allCommodities) dateHeaders,
833
+ headers]
834
+ _ -> [headers]
793
835
headers =
836
+ addHeaderBorders $
794
837
hCell " account" " account" :
795
838
case layout_ of
796
839
LayoutTidy ->
797
840
map headerCell
798
841
[" period" , " start_date" , " end_date" , " commodity" , " value" ]
842
+ LayoutBareWide -> dateHeaders >> map headerCell allCommodities
799
843
LayoutBare -> headerCell " commodity" : dateHeaders
800
844
_ -> dateHeaders
801
845
dateHeaders =
@@ -816,7 +860,7 @@ multiBalanceReportAsSpreadsheetParts fmt opts@ReportOpts{..} (PeriodicReport col
816
860
rowAsText Total simpleDateSpanCell tr
817
861
rowAsText rc dsCell =
818
862
map (map (fmap wbToText)) .
819
- multiBalanceRowAsCellBuilders fmt opts colspans rc dsCell
863
+ multiBalanceRowAsCellBuilders fmt opts colspans allCommodities rc dsCell
820
864
821
865
822
866
-- | Render a multi-column balance report as HTML.
@@ -834,10 +878,12 @@ multiBalanceReportAsSpreadsheet ::
834
878
((Maybe Int , Maybe Int ), [[Ods. Cell Ods. NumLines Text ]])
835
879
multiBalanceReportAsSpreadsheet ropts mbr =
836
880
let (header,body,total) =
837
- multiBalanceReportAsSpreadsheetParts oneLineNoCostFmt ropts mbr
881
+ multiBalanceReportAsSpreadsheetParts oneLineNoCostFmt ropts
882
+ (allCommoditiesFromPeriodicReport $ prRows mbr) mbr
838
883
in (if transpose_ ropts then swap *** Ods. transpose else id ) $
839
- ((Just 1 , case layout_ ropts of LayoutWide _ -> Just 1 ; _ -> Nothing ),
840
- header : body ++ total)
884
+ ((Just $ case layout_ ropts of LayoutBareWide -> 2 ; _ -> 1 ,
885
+ case layout_ ropts of LayoutWide _ -> Just 1 ; _ -> Nothing ),
886
+ header ++ body ++ total)
841
887
842
888
843
889
-- | Render a multi-column balance report as plain text suitable for console output.
@@ -908,19 +954,24 @@ multiBalanceReportAsTable opts@ReportOpts{summary_only_, average_, balanceaccum_
908
954
(concat rows)
909
955
where
910
956
colheadings = [" Commodity" | layout_ opts == LayoutBare ]
911
- ++ (if not summary_only_ then map (reportPeriodName balanceaccum_ spans) spans else [] )
957
+ ++ (if not summary_only_
958
+ then case layout_ opts of
959
+ LayoutBareWide -> spans >> allCommodities
960
+ _ -> map (reportPeriodName balanceaccum_ spans) spans
961
+ else [] )
912
962
++ [" Total" | multiBalanceHasTotalsColumn opts]
913
963
++ [" Average" | average_]
964
+ allCommodities = allCommoditiesFromPeriodicReport items
914
965
(accts, rows) = unzip $ fmap fullRowAsTexts items
915
966
where
916
967
fullRowAsTexts row = (replicate (length rs) (renderacct row), rs)
917
968
where
918
- rs = multiBalanceRowAsText opts row
969
+ rs = multiBalanceRowAsText opts allCommodities row
919
970
renderacct row' = T. replicate (prrIndent row' * 2 ) " " <> prrDisplayName row'
920
971
addtotalrow
921
972
| no_total_ opts = id
922
973
| otherwise =
923
- let totalrows = multiBalanceRowAsText opts tr
974
+ let totalrows = multiBalanceRowAsText opts allCommodities tr
924
975
rowhdrs = Group NoLine $ map Header $ totalRowHeadingText : replicate (length totalrows - 1 ) " "
925
976
colhdrs = Header [] -- unused, concatTables will discard
926
977
in (flip (concatTables SingleLine ) $ Table rowhdrs colhdrs totalrows)
@@ -929,12 +980,17 @@ multiBalanceReportAsTable opts@ReportOpts{summary_only_, average_, balanceaccum_
929
980
multiColumnTableInterRowBorder = NoLine
930
981
multiColumnTableInterColumnBorder = if pretty_ opts then SingleLine else NoLine
931
982
983
+ allCommoditiesFromPeriodicReport ::
984
+ [PeriodicReportRow a MixedAmount ] -> [CommoditySymbol ]
985
+ allCommoditiesFromPeriodicReport =
986
+ S. toAscList . foldMap (foldMap maCommodities . prrAmounts)
987
+
932
988
multiBalanceRowAsCellBuilders ::
933
- AmountFormat -> ReportOpts -> [DateSpan ] ->
989
+ AmountFormat -> ReportOpts -> [DateSpan ] -> [ CommoditySymbol ] ->
934
990
RowClass -> (DateSpan -> Ods. Cell Ods. NumLines Text ) ->
935
991
PeriodicReportRow a MixedAmount ->
936
992
[[Ods. Cell Ods. NumLines WideBuilder ]]
937
- multiBalanceRowAsCellBuilders bopts ropts@ ReportOpts {.. } colspans
993
+ multiBalanceRowAsCellBuilders bopts ropts@ ReportOpts {.. } colspans allCommodities
938
994
rc renderDateSpanCell (PeriodicReportRow _acct as rowtot rowavg) =
939
995
case layout_ of
940
996
LayoutWide width -> [fmap (cellFromMixedAmount bopts{displayMaxWidth= width}) clsamts]
@@ -945,6 +1001,8 @@ multiBalanceRowAsCellBuilders bopts ropts@ReportOpts{..} colspans
945
1001
. transpose -- each row becomes a list of Text quantities
946
1002
. map (cellsFromMixedAmount bopts{displayCommodity= False , displayCommodityOrder= Just cs, displayMinWidth= Nothing })
947
1003
$ clsamts
1004
+ LayoutBareWide -> [concatMap (cellsFromMixedAmount bopts{displayCommodity= False , displayCommodityOrder= Just allCommodities, displayMinWidth= Nothing })
1005
+ $ clsamts]
948
1006
LayoutTidy -> concat
949
1007
. zipWith (map . addDateColumns) colspans
950
1008
. map ( zipWith (\ c a -> [wbCell c, a]) cs
@@ -987,16 +1045,20 @@ multiBalanceHasTotalsColumn :: ReportOpts -> Bool
987
1045
multiBalanceHasTotalsColumn ropts =
988
1046
row_total_ ropts && balanceaccum_ ropts `notElem` [Cumulative , Historical ]
989
1047
990
- multiBalanceRowAsText :: ReportOpts -> PeriodicReportRow a MixedAmount -> [[WideBuilder ]]
991
- multiBalanceRowAsText opts =
1048
+ multiBalanceRowAsText ::
1049
+ ReportOpts -> [CommoditySymbol ] -> PeriodicReportRow a MixedAmount -> [[WideBuilder ]]
1050
+ multiBalanceRowAsText opts allCommodities =
992
1051
rawTableContent .
993
- multiBalanceRowAsCellBuilders oneLineNoCostFmt{displayColour= color_ opts} opts []
1052
+ multiBalanceRowAsCellBuilders oneLineNoCostFmt{displayColour= color_ opts}
1053
+ opts [] allCommodities
994
1054
Value simpleDateSpanCell
995
1055
996
- multiBalanceRowAsCsvText :: ReportOpts -> [DateSpan ] -> PeriodicReportRow a MixedAmount -> [[T. Text ]]
997
- multiBalanceRowAsCsvText opts colspans =
1056
+ multiBalanceRowAsCsvText ::
1057
+ ReportOpts -> [DateSpan ] -> [CommoditySymbol ] ->
1058
+ PeriodicReportRow a MixedAmount -> [[T. Text ]]
1059
+ multiBalanceRowAsCsvText opts colspans allCommodities =
998
1060
map (map (wbToText . Ods. cellContent)) .
999
- multiBalanceRowAsCellBuilders machineFmt opts colspans
1061
+ multiBalanceRowAsCellBuilders machineFmt opts colspans allCommodities
1000
1062
Value simpleDateSpanCell
1001
1063
1002
1064
@@ -1258,7 +1320,7 @@ budgetReportAsSpreadsheet
1258
1320
= (if transpose_ then Ods. transpose else id ) $
1259
1321
1260
1322
-- heading row
1261
- (map headerCell $
1323
+ (addHeaderBorders $ map headerCell $
1262
1324
" Account" :
1263
1325
[" Commodity" | layout_ == LayoutBare ]
1264
1326
++ concatMap (\ spn -> [showDateSpan spn, " budget" ]) colspans
0 commit comments