reg: support --value-at with -H (#329)
This commit is contained in:
		
							parent
							
								
									4c56baf842
								
							
						
					
					
						commit
						ad00da244b
					
				@ -71,13 +71,26 @@ postingsReport ropts@ReportOpts{..} q j =
 | 
			
		||||
      -- postings to be included in the report, and similarly-matched postings before the report start date
 | 
			
		||||
      (precedingps, reportps) = matchedPostingsBeforeAndDuring ropts q j reportspan
 | 
			
		||||
 | 
			
		||||
      -- We may be converting amounts to value, according to --value-at, as follows:
 | 
			
		||||
      -- (keep synced with hledger_options.m4.md)
 | 
			
		||||
      --  register -M --value-at
 | 
			
		||||
      --   transaction: convert each summary posting to value at posting date ; convert -H starting balance to value at day before report start
 | 
			
		||||
      --   period:      convert each summary posting to value at period end   ; convert -H starting balance to value at day before report start
 | 
			
		||||
      --   date:        convert each summary posting to value at date         ; convert -H starting balance to value at date
 | 
			
		||||
      --  register --value-at
 | 
			
		||||
      --   transaction: convert each posting to value at posting date         ; convert -H starting balance to value at day before report start
 | 
			
		||||
      --   period:      convert each posting to value at report end           ; convert -H starting balance to value at day before report start
 | 
			
		||||
      --   date:        convert each posting to value at date                 ; convert -H starting balance to value at date
 | 
			
		||||
      --  in all cases, the running total/average is calculated from the above numbers.
 | 
			
		||||
      -- "Day before report start" is a bit arbitrary.
 | 
			
		||||
 | 
			
		||||
      mvalueat = if value_ then Just value_at_ else Nothing
 | 
			
		||||
      today = fromMaybe (error' "postingsReport: ReportOpts today_ is unset so could not satisfy --value-at=now") today_
 | 
			
		||||
 | 
			
		||||
      -- Postings or summary pseudo postings to be displayed.
 | 
			
		||||
      -- If --value-at is present, we'll need to convert them to value as of various dates.
 | 
			
		||||
      displayps =
 | 
			
		||||
        let
 | 
			
		||||
          multiperiod = interval_ /= NoInterval
 | 
			
		||||
          mvalueat    = if value_ then Just value_at_ else Nothing
 | 
			
		||||
          today       = fromMaybe (error' "postingsReport: ReportOpts today_ is unset so could not satisfy --value-at=now") today_
 | 
			
		||||
        in
 | 
			
		||||
          if multiperiod then
 | 
			
		||||
            let
 | 
			
		||||
@ -86,6 +99,7 @@ postingsReport ropts@ReportOpts{..} q j =
 | 
			
		||||
            in case mvalueat of
 | 
			
		||||
              Nothing            -> [(p                                       , periodend) | (p,periodend) <- summaryps]
 | 
			
		||||
              Just AtTransaction -> [(postingValueAtDate j (postingDate p) p  , periodend) | (p,periodend) <- summaryps]
 | 
			
		||||
                --   ^ XXX shouldn't this value the individual ps at postingdate before summarising
 | 
			
		||||
              Just AtPeriod      -> [(postingValueAtDate j periodlastday p    , periodend) | (p,periodend) <- summaryps
 | 
			
		||||
                                    ,let periodlastday = maybe
 | 
			
		||||
                                           (error' "postingsReport: expected a subperiod end date") -- XXX shouldn't happen
 | 
			
		||||
@ -105,8 +119,10 @@ postingsReport ropts@ReportOpts{..} q j =
 | 
			
		||||
              Just AtNow         -> [(postingValueAtDate j today p              , Nothing) | p <- reportps]
 | 
			
		||||
              Just (AtDate d)    -> [(postingValueAtDate j d p                  , Nothing) | p <- reportps]
 | 
			
		||||
 | 
			
		||||
      -- For -H: postings preceding the report period, to calculate the initial running total/average.
 | 
			
		||||
 | 
			
		||||
      -- posting report items ready for display
 | 
			
		||||
      items = dbg1 "postingsReport items" $ postingsReportItems displayps (nullposting,Nothing) whichdate depth startbal runningcalc startnum
 | 
			
		||||
      items = dbg1 "postingsReport items" $ postingsReportItems displayps (nullposting,Nothing) whichdate depth valuedstartbal runningcalc startnum
 | 
			
		||||
        where
 | 
			
		||||
          historical = balancetype_ == HistoricalBalance
 | 
			
		||||
          precedingsum = sumPostings precedingps
 | 
			
		||||
@ -114,6 +130,25 @@ postingsReport ropts@ReportOpts{..} q j =
 | 
			
		||||
                       | otherwise        = divideMixedAmount (fromIntegral $ length precedingps) precedingsum
 | 
			
		||||
          startbal | average_  = if historical then precedingavg else 0
 | 
			
		||||
                   | otherwise = if historical then precedingsum else 0
 | 
			
		||||
          -- For --value-at: convert the initial running total/average to value.
 | 
			
		||||
          -- For --value-at=transaction, we don't bother valuing each
 | 
			
		||||
          -- preceding posting at posting date - how useful would that
 | 
			
		||||
          -- be ? Just value the initial sum/average at report start date.
 | 
			
		||||
          valuedstartbal = case mvalueat of
 | 
			
		||||
            Nothing            -> startbal
 | 
			
		||||
            Just AtTransaction -> mixedAmountValue prices daybeforereportstart startbal
 | 
			
		||||
            Just AtPeriod      -> mixedAmountValue prices daybeforereportstart startbal
 | 
			
		||||
            Just AtNow         -> mixedAmountValue prices today       startbal
 | 
			
		||||
            Just (AtDate d)    -> mixedAmountValue prices d           startbal
 | 
			
		||||
            where
 | 
			
		||||
              daybeforereportstart = maybe
 | 
			
		||||
                                     (error' "postingsReport: expected a non-empty journal") -- XXX shouldn't happen
 | 
			
		||||
                                     (addDays (-1))
 | 
			
		||||
                                     $ reportPeriodOrJournalStart ropts j
 | 
			
		||||
              -- prices are in parse order - sort into date then parse order,
 | 
			
		||||
              -- & reversed for quick lookup of the latest price.
 | 
			
		||||
              prices = reverse $ sortOn mpdate $ jmarketprices j
 | 
			
		||||
 | 
			
		||||
          startnum = if historical then length precedingps + 1 else 1
 | 
			
		||||
          runningcalc = registerRunningCalculationFn ropts
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -33,6 +33,8 @@ module Hledger.Reports.ReportOptions (
 | 
			
		||||
  specifiedStartEndDates,
 | 
			
		||||
  specifiedStartDate,
 | 
			
		||||
  specifiedEndDate,
 | 
			
		||||
  reportPeriodStart,
 | 
			
		||||
  reportPeriodOrJournalStart,
 | 
			
		||||
  reportPeriodLastDay,
 | 
			
		||||
  reportPeriodOrJournalLastDay,
 | 
			
		||||
 | 
			
		||||
@ -431,6 +433,8 @@ queryOptsFromOpts d ReportOpts{..} = flagsqopts ++ argsqopts
 | 
			
		||||
    flagsqopts = []
 | 
			
		||||
    argsqopts = snd $ parseQuery d (T.pack query_)
 | 
			
		||||
 | 
			
		||||
-- Report dates.
 | 
			
		||||
 | 
			
		||||
-- | The effective report span is the start and end dates specified by
 | 
			
		||||
-- options or queries, or otherwise the earliest and latest transaction or 
 | 
			
		||||
-- posting dates in the journal. If no dates are specified by options/queries
 | 
			
		||||
@ -470,10 +474,32 @@ specifiedStartDate ropts = fst <$> specifiedStartEndDates ropts
 | 
			
		||||
specifiedEndDate :: ReportOpts -> IO (Maybe Day)
 | 
			
		||||
specifiedEndDate ropts = snd <$> specifiedStartEndDates ropts
 | 
			
		||||
 | 
			
		||||
-- Get the last day of the overall report period.
 | 
			
		||||
-- Some pure alternatives to the above. XXX review/clean up
 | 
			
		||||
 | 
			
		||||
-- Get the report's start date.
 | 
			
		||||
-- If no report period is specified, will be Nothing.
 | 
			
		||||
-- Will also be Nothing if ReportOpts does not have today_ set,
 | 
			
		||||
-- since we need that to get the report period robustly.
 | 
			
		||||
-- since we need that to get the report period robustly
 | 
			
		||||
-- (unlike reportStartDate, which looks up the date with IO.)
 | 
			
		||||
reportPeriodStart :: ReportOpts -> Maybe Day
 | 
			
		||||
reportPeriodStart ropts@ReportOpts{..} = do
 | 
			
		||||
  t <- today_
 | 
			
		||||
  queryStartDate False $ queryFromOpts t ropts
 | 
			
		||||
 | 
			
		||||
-- Get the report's start date, or if no report period is specified,
 | 
			
		||||
-- the journal's start date (the earliest posting date). If there's no
 | 
			
		||||
-- report period and nothing in the journal, will be Nothing.
 | 
			
		||||
reportPeriodOrJournalStart :: ReportOpts -> Journal -> Maybe Day
 | 
			
		||||
reportPeriodOrJournalStart ropts@ReportOpts{..} j =
 | 
			
		||||
  reportPeriodStart ropts <|> journalStartDate False j
 | 
			
		||||
 | 
			
		||||
-- Get the last day of the overall report period.
 | 
			
		||||
-- This the inclusive end date (one day before the 
 | 
			
		||||
-- more commonly used, exclusive, report end date).
 | 
			
		||||
-- If no report period is specified, will be Nothing.
 | 
			
		||||
-- Will also be Nothing if ReportOpts does not have today_ set,
 | 
			
		||||
-- since we need that to get the report period robustly
 | 
			
		||||
-- (unlike reportEndDate, which looks up the date with IO.)
 | 
			
		||||
reportPeriodLastDay :: ReportOpts -> Maybe Day
 | 
			
		||||
reportPeriodLastDay ropts@ReportOpts{..} = do
 | 
			
		||||
  t <- today_
 | 
			
		||||
@ -481,10 +507,10 @@ reportPeriodLastDay ropts@ReportOpts{..} = do
 | 
			
		||||
  qend <- queryEndDate False q
 | 
			
		||||
  return $ addDays (-1) qend
 | 
			
		||||
 | 
			
		||||
-- Get the last day of the overall report period,
 | 
			
		||||
-- or if no report period is specified, the last day of the journal
 | 
			
		||||
-- (ie the latest posting date).
 | 
			
		||||
-- If there's no report period and nothing in the journal, will be Nothing.
 | 
			
		||||
-- Get the last day of the overall report period, or if no report
 | 
			
		||||
-- period is specified, the last day of the journal (ie the latest
 | 
			
		||||
-- posting date). If there's no report period and nothing in the
 | 
			
		||||
-- journal, will be Nothing.
 | 
			
		||||
reportPeriodOrJournalLastDay :: ReportOpts -> Journal -> Maybe Day
 | 
			
		||||
reportPeriodOrJournalLastDay ropts@ReportOpts{..} j =
 | 
			
		||||
  reportPeriodLastDay ropts <|> journalEndDate False j
 | 
			
		||||
 | 
			
		||||
@ -231,33 +231,55 @@ $ hledger -f- reg -V
 | 
			
		||||
2000/02/01                      (a)                            4 B           8 B
 | 
			
		||||
2000/03/01                      (a)                            4 B          12 B
 | 
			
		||||
 | 
			
		||||
# register with -H (starting balance)
 | 
			
		||||
 | 
			
		||||
# 19. register with starting balance, valued at transaction.
 | 
			
		||||
# Shows the running total of the posting amount values (not the values of the running total).
 | 
			
		||||
# The starting balance is 1 A, valued at 2000/1/31 (day before report start), which is 5 B.
 | 
			
		||||
$ hledger -f- reg --value-at=transaction -b 200002 -H
 | 
			
		||||
2000/02/01                      (a)                            2 B           7 B
 | 
			
		||||
2000/03/01                      (a)                            3 B          10 B
 | 
			
		||||
 
 | 
			
		||||
# 20. register with starting balance, valued at period end.
 | 
			
		||||
# That is unspecified so the last posting date is used, ie 2000/3/1, so the price is 3 B.
 | 
			
		||||
# Starting balance is 5 B as above.
 | 
			
		||||
$ hledger -f- reg --value-at=period -b 200002 -H
 | 
			
		||||
2000/02/01                      (a)                            3 B           8 B
 | 
			
		||||
2000/03/01                      (a)                            3 B          11 B
 | 
			
		||||
 | 
			
		||||
# 21. register with starting balance, valued at specified date (when the price is 5 B).
 | 
			
		||||
# Starting balance is 5 B as above.
 | 
			
		||||
$ hledger -f- reg --value-at=2000-01-15 -b 200002 -H
 | 
			
		||||
2000/02/01                      (a)                            5 B          10 B
 | 
			
		||||
2000/03/01                      (a)                            5 B          15 B
 | 
			
		||||
 | 
			
		||||
# register, periodic
 | 
			
		||||
 | 
			
		||||
# 19. periodic register report valued at transaction
 | 
			
		||||
# 22. periodic register report valued at transaction
 | 
			
		||||
$ hledger -f- reg --value-at=transaction -M
 | 
			
		||||
2000/01                 a                                      1 B           1 B
 | 
			
		||||
2000/02                 a                                      2 B           3 B
 | 
			
		||||
2000/03                 a                                      3 B           6 B
 | 
			
		||||
 
 | 
			
		||||
# 20. periodic register report valued at period end
 | 
			
		||||
# 23. periodic register report valued at period end
 | 
			
		||||
$ hledger -f- reg --value-at=period -M
 | 
			
		||||
2000/01                 a                                      5 B           5 B
 | 
			
		||||
2000/02                 a                                      2 B           7 B
 | 
			
		||||
2000/03                 a                                      3 B          10 B
 | 
			
		||||
 | 
			
		||||
# 21. periodic register report valued at specified date
 | 
			
		||||
# 24. periodic register report valued at specified date
 | 
			
		||||
$ hledger -f- reg --value-at=2000-01-15 -M
 | 
			
		||||
2000/01                 a                                      5 B           5 B
 | 
			
		||||
2000/02                 a                                      5 B          10 B
 | 
			
		||||
2000/03                 a                                      5 B          15 B
 | 
			
		||||
 | 
			
		||||
# 22. periodic register report valued today
 | 
			
		||||
# 25. periodic register report valued today
 | 
			
		||||
$ hledger -f- reg --value-at=now -M
 | 
			
		||||
2000/01                 a                                      4 B           4 B
 | 
			
		||||
2000/02                 a                                      4 B           8 B
 | 
			
		||||
2000/03                 a                                      4 B          12 B
 | 
			
		||||
 | 
			
		||||
# 23. periodic register report valued at default date (same as above)
 | 
			
		||||
# 26. periodic register report valued at default date (same as above)
 | 
			
		||||
$ hledger -f- reg -V -M
 | 
			
		||||
2000/01                 a                                      4 B           4 B
 | 
			
		||||
2000/02                 a                                      4 B           8 B
 | 
			
		||||
@ -265,31 +287,31 @@ $ hledger -f- reg -V -M
 | 
			
		||||
 | 
			
		||||
# balance
 | 
			
		||||
 | 
			
		||||
# 24. single column balance report valued at transaction
 | 
			
		||||
# 27. single column balance report valued at transaction
 | 
			
		||||
$ hledger -f- bal --value-at=transaction
 | 
			
		||||
                 6 B  a
 | 
			
		||||
--------------------
 | 
			
		||||
                 6 B
 | 
			
		||||
 
 | 
			
		||||
# 25. single column balance report valued at period end
 | 
			
		||||
# 28. single column balance report valued at period end
 | 
			
		||||
$ hledger -f- bal --value-at=period
 | 
			
		||||
                 9 B  a
 | 
			
		||||
--------------------
 | 
			
		||||
                 9 B
 | 
			
		||||
 | 
			
		||||
# 26. single column balance report valued at specified date
 | 
			
		||||
# 29. single column balance report valued at specified date
 | 
			
		||||
$ hledger -f- bal --value-at=2000-01-15
 | 
			
		||||
                15 B  a
 | 
			
		||||
--------------------
 | 
			
		||||
                15 B
 | 
			
		||||
 | 
			
		||||
# 27. single column balance report valued today
 | 
			
		||||
# 30. single column balance report valued today
 | 
			
		||||
$ hledger -f- bal --value-at=now
 | 
			
		||||
                12 B  a
 | 
			
		||||
--------------------
 | 
			
		||||
                12 B
 | 
			
		||||
 | 
			
		||||
# 28. single column balance report valued at default date (same as above)
 | 
			
		||||
# 31. single column balance report valued at default date (same as above)
 | 
			
		||||
$ hledger -f- bal -V
 | 
			
		||||
                12 B  a
 | 
			
		||||
--------------------
 | 
			
		||||
@ -297,7 +319,7 @@ $ hledger -f- bal -V
 | 
			
		||||
 | 
			
		||||
# balance, periodic
 | 
			
		||||
 | 
			
		||||
# 29. multicolumn balance report valued at transaction
 | 
			
		||||
# 32. multicolumn balance report valued at transaction
 | 
			
		||||
$ hledger -f- bal -MTA --value-at=transaction
 | 
			
		||||
Balance changes in 2000q1:
 | 
			
		||||
 | 
			
		||||
@ -307,7 +329,7 @@ Balance changes in 2000q1:
 | 
			
		||||
---++---------------------------------
 | 
			
		||||
   || 1 B  2 B  3 B      6 B      2 B 
 | 
			
		||||
 
 | 
			
		||||
# 30. multicolumn balance report valued at period end
 | 
			
		||||
# 33. multicolumn balance report valued at period end
 | 
			
		||||
$ hledger -f- bal -M --value-at=period
 | 
			
		||||
Balance changes in 2000q1:
 | 
			
		||||
 | 
			
		||||
@ -317,7 +339,7 @@ Balance changes in 2000q1:
 | 
			
		||||
---++---------------
 | 
			
		||||
   || 5 B  2 B  3 B 
 | 
			
		||||
 | 
			
		||||
# 31. multicolumn balance report valued at period end with -T or -A
 | 
			
		||||
# 34. multicolumn balance report valued at period end with -T or -A
 | 
			
		||||
$ hledger -f- bal -M --value-at=period -TA
 | 
			
		||||
Balance changes in 2000q1:
 | 
			
		||||
 | 
			
		||||
@ -329,7 +351,7 @@ Balance changes in 2000q1:
 | 
			
		||||
# >2 /not yet supported/
 | 
			
		||||
# >=1
 | 
			
		||||
 | 
			
		||||
# 32. multicolumn balance report valued at other date
 | 
			
		||||
# 35. multicolumn balance report valued at other date
 | 
			
		||||
$ hledger -f- bal -MTA --value-at=2000-01-15
 | 
			
		||||
Balance changes in 2000q1:
 | 
			
		||||
 | 
			
		||||
@ -339,7 +361,7 @@ Balance changes in 2000q1:
 | 
			
		||||
---++---------------------------------
 | 
			
		||||
   || 5 B  5 B  5 B     15 B      5 B 
 | 
			
		||||
 | 
			
		||||
# 33. multicolumn balance report valued today (with today >= 2000-04-01)
 | 
			
		||||
# 36. multicolumn balance report valued today (with today >= 2000-04-01)
 | 
			
		||||
$ hledger -f- bal -M --value-at=now
 | 
			
		||||
Balance changes in 2000q1:
 | 
			
		||||
 | 
			
		||||
@ -349,7 +371,7 @@ Balance changes in 2000q1:
 | 
			
		||||
---++---------------
 | 
			
		||||
   || 4 B  4 B  4 B 
 | 
			
		||||
 | 
			
		||||
# 34. multicolumn balance report valued at default date (same as above)
 | 
			
		||||
# 37. multicolumn balance report valued at default date (same as above)
 | 
			
		||||
$ hledger -f- bal -M -V
 | 
			
		||||
Balance changes in 2000q1:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user