cln: Move column grouping functions form Report.PostingsReport to Data.Dates.

This commit is contained in:
Stephen Morgan 2021-09-17 16:15:32 +10:00 committed by Simon Michael
parent 8a6d824900
commit 35c33f342b
2 changed files with 31 additions and 21 deletions

View File

@ -66,6 +66,7 @@ module Hledger.Data.Dates (
latestSpanContaining,
smartdate,
splitSpan,
groupByDateSpan,
fixSmartDate,
fixSmartDateStr,
fixSmartDateStrEither,
@ -86,25 +87,28 @@ import Control.Applicative.Permutations
import Control.Monad (guard, unless)
import "base-compat-batteries" Data.List.Compat
import Data.Char (digitToInt, isDigit, ord)
import Data.Default
import Data.Default (def)
import Data.Foldable (asum)
import Data.Function (on)
import Data.Functor (($>))
import Data.Maybe
import Data.Maybe (catMaybes, fromMaybe, isJust, mapMaybe)
import Data.Ord (comparing)
import qualified Data.Set as Set
import Data.Text (Text)
import qualified Data.Text as T
import Data.Time.Format hiding (months)
import Data.Time.Calendar
import Data.Time.Calendar.OrdinalDate
import Data.Time.Clock
import Data.Time.LocalTime
(Day, addDays, addGregorianYearsClip, addGregorianMonthsClip, diffDays,
fromGregorian, fromGregorianValid, toGregorian)
import Data.Time.Calendar.OrdinalDate (fromMondayStartWeek, mondayStartWeek)
import Data.Time.Clock (UTCTime, diffUTCTime)
import Data.Time.LocalTime (getZonedTime, localDay, zonedTimeToLocalTime)
import Safe (headMay, lastMay, maximumMay, minimumMay)
import Text.Megaparsec
import Text.Megaparsec.Char
import Text.Megaparsec.Char (char, char', digitChar, string, string')
import Text.Megaparsec.Char.Lexer (decimal)
import Text.Megaparsec.Custom
import Text.Printf
import Text.Megaparsec.Custom (customErrorBundlePretty)
import Text.Printf (printf)
import Hledger.Data.Types
import Hledger.Data.Period
@ -273,6 +277,22 @@ spanContainsDate (DateSpan (Just b) (Just e)) d = d >= b && d < e
periodContainsDate :: Period -> Day -> Bool
periodContainsDate p = spanContainsDate (periodAsDateSpan p)
-- | Group elements based on where they fall in a list of 'DateSpan's without
-- gaps. The precondition is not checked.
groupByDateSpan :: Bool -> (a -> Day) -> [DateSpan] -> [a] -> [(DateSpan, [a])]
groupByDateSpan showempty date colspans =
groupByCols colspans
. dropWhile (beforeStart . fst)
. sortBy (comparing fst)
. map (\x -> (date x, x))
where
groupByCols [] _ = []
groupByCols (c:cs) [] = if showempty then (c, []) : groupByCols cs [] else []
groupByCols (c:cs) ps = (c, map snd matches) : groupByCols cs later
where (matches, later) = span ((spanEnd c >) . Just . fst) ps
beforeStart = maybe (const True) (>) $ spanStart =<< headMay colspans
-- | Calculate the intersection of a number of datespans.
spansIntersect [] = nulldatespan
spansIntersect [d] = d

View File

@ -21,10 +21,9 @@ module Hledger.Reports.PostingsReport (
)
where
import Data.List (nub, sortBy, sortOn)
import Data.List (nub, sortOn)
import Data.List.Extra (nubSort)
import Data.Maybe (fromMaybe, isJust, isNothing)
import Data.Ord (comparing)
import Data.Text (Text)
import Data.Time.Calendar (Day)
import Safe (headMay)
@ -176,22 +175,13 @@ mkpostingsReportItem showdate showdesc wd mperiod p b =
-- Each summary posting will have a non-Nothing interval end date.
summarisePostingsByInterval :: Interval -> WhichDate -> Maybe Int -> Bool -> DateSpan -> [Posting] -> [SummaryPosting]
summarisePostingsByInterval interval wd mdepth showempty reportspan =
concatMap (\(s,ps) -> summarisePostingsInDateSpan s wd mdepth showempty $ map snd ps)
concatMap (\(s,ps) -> summarisePostingsInDateSpan s wd mdepth showempty ps)
-- Group postings into their columns. We try to be efficient, since
-- there can possibly be a very large number of intervals (cf #1683)
. groupByCols colspans
. dropWhile (beforeStart . fst)
. sortBy (comparing fst)
. map (\p -> (getDate p, p))
. groupByDateSpan showempty getDate colspans
where
groupByCols [] _ = []
groupByCols (c:cs) [] = if showempty then (c,[]) : groupByCols cs [] else []
groupByCols (c:cs) ps = (c, matches) : groupByCols cs later
where (matches, later) = span ((spanEnd c >) . Just . fst) ps
-- The date spans to be included as report columns.
colspans = splitSpan interval reportspan
beforeStart = maybe (const True) (>) $ spanStart =<< headMay colspans
getDate = case wd of
PrimaryDate -> postingDate
SecondaryDate -> postingDate2