lib,ui: Do all cost conversion and price stripping in journalSelectingAmountFromOpts.
This commit is contained in:
		
							parent
							
								
									0078f1a520
								
							
						
					
					
						commit
						53611be6e9
					
				| @ -84,45 +84,35 @@ accountTransactionsReport rspec@ReportSpec{rsOpts=ropts} j reportq thisacctq = i | |||||||
|   where |   where | ||||||
|     -- a depth limit should not affect the account transactions report |     -- a depth limit should not affect the account transactions report | ||||||
|     -- seems unnecessary for some reason XXX |     -- seems unnecessary for some reason XXX | ||||||
|     reportq' = -- filterQuery (not . queryIsDepth) |     reportq'   = reportq -- filterQuery (not . queryIsDepth) | ||||||
|                reportq |     symq       = filterQuery queryIsSym reportq' | ||||||
| 
 |     realq      = filterQuery queryIsReal reportq' | ||||||
|     -- get all transactions |     statusq    = filterQuery queryIsStatus reportq' | ||||||
|     ts1 = |     prices     = journalPriceOracle (infer_value_ ropts) j | ||||||
|       -- ptraceAtWith 5 (("ts1:\n"++).pshowTransactions) $ |     styles     = journalCommodityStyles j | ||||||
|       jtxns j |  | ||||||
| 
 |  | ||||||
|     -- apply any cur:SYM filters in reportq' |  | ||||||
|     symq  = filterQuery queryIsSym reportq' |  | ||||||
|     ts2 = |  | ||||||
|       ptraceAtWith 5 (("ts2:\n"++).pshowTransactions) $ |  | ||||||
|       (if queryIsNull symq then id else map (filterTransactionAmounts symq)) ts1 |  | ||||||
| 
 |  | ||||||
|     -- keep just the transactions affecting this account (via possibly realness or status-filtered postings) |  | ||||||
|     realq = filterQuery queryIsReal reportq' |  | ||||||
|     statusq = filterQuery queryIsStatus reportq' |  | ||||||
|     ts3 = |  | ||||||
|       traceAt 3 ("thisacctq: "++show thisacctq) $ |  | ||||||
|       ptraceAtWith 5 (("ts3:\n"++).pshowTransactions) $ |  | ||||||
|       filter (matchesTransaction thisacctq . filterTransactionPostings (And [realq, statusq])) ts2 |  | ||||||
| 
 |  | ||||||
|     -- maybe convert these transactions to cost or value |  | ||||||
|     -- PARTIAL: |  | ||||||
|     prices = journalPriceOracle (infer_value_ ropts) j |  | ||||||
|     styles = journalCommodityStyles j |  | ||||||
|     periodlast = |     periodlast = | ||||||
|       fromMaybe (error' "journalApplyValuation: expected a non-empty journal") $ -- XXX shouldn't happen |       fromMaybe (error' "journalApplyValuation: expected a non-empty journal") $ -- XXX shouldn't happen | ||||||
|       reportPeriodOrJournalLastDay rspec j |       reportPeriodOrJournalLastDay rspec j | ||||||
|     tval = transactionApplyCostValuation prices styles periodlast (rsToday rspec) (cost_ ropts) $ value_ ropts |     pvalue = maybe id (postingApplyValuation prices styles periodlast (rsToday rspec)) $ value_ ropts | ||||||
|     ts4 = |  | ||||||
|       ptraceAtWith 5 (("ts4:\n"++).pshowTransactions) $ |  | ||||||
|       map tval ts3 |  | ||||||
| 
 | 
 | ||||||
|     -- sort by the transaction's register date, for accurate starting balance |     -- sort by the transaction's register date, for accurate starting balance | ||||||
|     -- these are not yet filtered by tdate, we want to search them all for priorps |     -- these are not yet filtered by tdate, we want to search them all for priorps | ||||||
|     ts5 = |     transactions = | ||||||
|       ptraceAtWith 5 (("ts5:\n"++).pshowTransactions) $ |         ptraceAtWith 5 (("ts5:\n"++).pshowTransactions) | ||||||
|       sortBy (comparing (transactionRegisterDate reportq' thisacctq)) ts4 |       . sortBy (comparing (transactionRegisterDate reportq' thisacctq)) | ||||||
|  |       . jtxns | ||||||
|  |       -- maybe convert these transactions to cost or value | ||||||
|  |       . ptraceAtWith 5 (("ts4:\n"++).pshowTransactions.jtxns) | ||||||
|  |       . journalMapPostings pvalue | ||||||
|  |       . journalSelectingAmountFromOpts ropts | ||||||
|  |       -- keep just the transactions affecting this account (via possibly realness or status-filtered postings) | ||||||
|  |       . traceAt 3 ("thisacctq: "++show thisacctq) | ||||||
|  |       . ptraceAtWith 5 (("ts3:\n"++).pshowTransactions.jtxns) | ||||||
|  |       . filterJournalTransactions thisacctq | ||||||
|  |       . filterJournalPostings (And [realq, statusq]) | ||||||
|  |       -- apply any cur:SYM filters in reportq' | ||||||
|  |       . ptraceAtWith 5 (("ts2:\n"++).pshowTransactions.jtxns) | ||||||
|  |       $ (if queryIsNull symq then id else filterJournalAmounts symq) j | ||||||
| 
 | 
 | ||||||
|     startbal |     startbal | ||||||
|       | balancetype_ ropts == HistoricalBalance = sumPostings priorps |       | balancetype_ ropts == HistoricalBalance = sumPostings priorps | ||||||
| @ -132,7 +122,7 @@ accountTransactionsReport rspec@ReportSpec{rsOpts=ropts} j reportq thisacctq = i | |||||||
|                   filter (matchesPosting |                   filter (matchesPosting | ||||||
|                           (dbg5 "priorq" $ |                           (dbg5 "priorq" $ | ||||||
|                            And [thisacctq, tostartdateq, datelessreportq])) |                            And [thisacctq, tostartdateq, datelessreportq])) | ||||||
|                          $ transactionsPostings ts5 |                          $ transactionsPostings transactions | ||||||
|         tostartdateq = |         tostartdateq = | ||||||
|           case mstartdate of |           case mstartdate of | ||||||
|             Just _  -> Date (DateSpan Nothing mstartdate) |             Just _  -> Date (DateSpan Nothing mstartdate) | ||||||
| @ -149,7 +139,7 @@ accountTransactionsReport rspec@ReportSpec{rsOpts=ropts} j reportq thisacctq = i | |||||||
|     items = reverse $ |     items = reverse $ | ||||||
|             accountTransactionsReportItems reportq' thisacctq startbal maNegate $ |             accountTransactionsReportItems reportq' thisacctq startbal maNegate $ | ||||||
|             (if filtertxns then filter (reportq' `matchesTransaction`) else id) $ |             (if filtertxns then filter (reportq' `matchesTransaction`) else id) $ | ||||||
|             ts5 |             transactions | ||||||
| 
 | 
 | ||||||
| pshowTransactions :: [Transaction] -> String | pshowTransactions :: [Transaction] -> String | ||||||
| pshowTransactions = pshow . map (\t -> unwords [show $ tdate t, T.unpack $ tdescription t]) | pshowTransactions = pshow . map (\t -> unwords [show $ tdate t, T.unpack $ tdescription t]) | ||||||
|  | |||||||
| @ -33,15 +33,18 @@ type EntriesReportItem = Transaction | |||||||
| 
 | 
 | ||||||
| -- | Select transactions for an entries report. | -- | Select transactions for an entries report. | ||||||
| entriesReport :: ReportSpec -> Journal -> EntriesReport | entriesReport :: ReportSpec -> Journal -> EntriesReport | ||||||
| entriesReport rspec@ReportSpec{rsOpts=ropts@ReportOpts{..}} j@Journal{..} = | entriesReport rspec@ReportSpec{rsOpts=ropts@ReportOpts{..}} j = | ||||||
|   sortBy (comparing getdate) $ filter (rsQuery rspec `matchesTransaction`) $ map tvalue jtxns |   sortBy (comparing getdate) . jtxns . filterJournalTransactions (rsQuery rspec) | ||||||
|  |     . journalMapPostings pvalue | ||||||
|  |     $ journalSelectingAmountFromOpts ropts{show_costs_=True} j | ||||||
|   where |   where | ||||||
|     getdate = transactionDateFn ropts |     getdate = transactionDateFn ropts | ||||||
|     -- We may be converting posting amounts to value, per hledger_options.m4.md "Effect of --value on reports". |     -- We may be converting posting amounts to value, per hledger_options.m4.md "Effect of --value on reports". | ||||||
|     tvalue t@Transaction{..} = t{tpostings=map pvalue tpostings} |     pvalue = maybe id (postingApplyValuation priceoracle styles periodlast (rsToday rspec)) value_ | ||||||
|       where |       where | ||||||
|         pvalue = postingApplyCostValuation (journalPriceOracle infer_value_ j) (journalCommodityStyles j) periodlast (rsToday rspec) cost_ value_ |         priceoracle = journalPriceOracle infer_value_ j | ||||||
|           where periodlast  = fromMaybe (rsToday rspec) $ reportPeriodOrJournalLastDay rspec j |         styles = journalCommodityStyles j | ||||||
|  |         periodlast  = fromMaybe (rsToday rspec) $ reportPeriodOrJournalLastDay rspec j | ||||||
| 
 | 
 | ||||||
| tests_EntriesReport = tests "EntriesReport" [ | tests_EntriesReport = tests "EntriesReport" [ | ||||||
|   tests "entriesReport" [ |   tests "entriesReport" [ | ||||||
|  | |||||||
| @ -248,8 +248,9 @@ getPostings :: ReportSpec -> Journal -> [(Posting, Day)] | |||||||
| getPostings ReportSpec{rsQuery=query,rsOpts=ropts} = | getPostings ReportSpec{rsQuery=query,rsOpts=ropts} = | ||||||
|     map (\p -> (p, date p)) . |     map (\p -> (p, date p)) . | ||||||
|     journalPostings . |     journalPostings . | ||||||
|     filterJournalAmounts symq .    -- remove amount parts excluded by cur: |     filterJournalAmounts symq .      -- remove amount parts excluded by cur: | ||||||
|     filterJournalPostings reportq  -- remove postings not matched by (adjusted) query |     filterJournalPostings reportq .  -- remove postings not matched by (adjusted) query | ||||||
|  |     journalSelectingAmountFromOpts ropts | ||||||
|   where |   where | ||||||
|     symq = dbg3 "symq" . filterQuery queryIsSym $ dbg3 "requested q" query |     symq = dbg3 "symq" . filterQuery queryIsSym $ dbg3 "requested q" query | ||||||
|     -- The user's query with no depth limit, and expanded to the report span |     -- The user's query with no depth limit, and expanded to the report span | ||||||
| @ -553,25 +554,24 @@ cumulativeSum :: (DateSpan -> Account -> Account) -> Account -> Map DateSpan Acc | |||||||
| cumulativeSum value start = snd . M.mapAccumWithKey accumValued start | cumulativeSum value start = snd . M.mapAccumWithKey accumValued start | ||||||
|   where accumValued startAmt date newAmt = let s = sumAcct startAmt newAmt in (s, value date s) |   where accumValued startAmt date newAmt = let s = sumAcct startAmt newAmt in (s, value date s) | ||||||
| 
 | 
 | ||||||
| -- | Calculate the Posting and Account valuation functions required by this | -- | Calculate the Posting and Account valuation functions required by this MultiBalanceReport. | ||||||
| -- MultiBalanceReport. |  | ||||||
| postingAndAccountValuations :: ReportSpec -> Journal -> PriceOracle | postingAndAccountValuations :: ReportSpec -> Journal -> PriceOracle | ||||||
|                             -> (DateSpan -> Posting -> Posting, DateSpan -> Account -> Account) |                             -> (DateSpan -> Posting -> Posting, DateSpan -> Account -> Account) | ||||||
| postingAndAccountValuations ReportSpec{rsToday=today, rsOpts=ropts} j priceoracle = case value_ ropts of | postingAndAccountValuations ReportSpec{rsToday=today, rsOpts=ropts} j priceoracle = case value_ ropts of | ||||||
|  |     -- If we're doing no valuation, just return the identity functions. | ||||||
|  |     Nothing          -> (const id, const id) | ||||||
|     -- If we're doing AtEnd valuation, we may need to value the same posting at different dates |     -- If we're doing AtEnd valuation, we may need to value the same posting at different dates | ||||||
|     -- (for example, when preparing a ValueChange report). So we should only convert to cost and |     -- (for example, when preparing a ValueChange report). So we should do valuation on the Accounts. | ||||||
|     -- maybe strip prices from the Posting, and should do valuation on the Accounts. |     Just v@(AtEnd _) -> (const id, avalue v) | ||||||
|     Just v@(AtEnd _) -> (pvalue Nothing, avalue v) |     -- Otherwise, all valuation should be done on the Postings. | ||||||
|     -- Otherwise, all costing and valuation should be done on the Postings. |     Just v           -> (pvalue v, const id) | ||||||
|     _                -> (pvalue (value_ ropts), const id) |  | ||||||
|   where |   where | ||||||
|     -- For a Posting: convert to cost, apply valuation, then strip prices if we don't need them (See issue #1507). |     -- For a Posting: convert to cost, apply valuation, then strip prices if we don't need them (See issue #1507). | ||||||
|     pvalue v span = maybeStripPrices . postingApplyCostValuation priceoracle styles (end span) today (cost_ ropts) v |     pvalue v span = postingApplyValuation priceoracle styles (end span) today v | ||||||
|     -- For an Account: Apply valuation to both the inclusive and exclusive balances. |     -- For an Account: Apply valuation to both the inclusive and exclusive balances. | ||||||
|     avalue v span a = a{aibalance = value (aibalance a), aebalance = value (aebalance a)} |     avalue v span a = a{aibalance = value (aibalance a), aebalance = value (aebalance a)} | ||||||
|       where value = mixedAmountApplyValuation priceoracle styles (end span) today (error "multiBalanceReport: did not expect amount valuation to be called ") v  -- PARTIAL: should not happen |       where value = mixedAmountApplyValuation priceoracle styles (end span) today (error "multiBalanceReport: did not expect amount valuation to be called ") v  -- PARTIAL: should not happen | ||||||
| 
 | 
 | ||||||
|     maybeStripPrices = if show_costs_ ropts then id else postingStripPrices |  | ||||||
|     end = maybe (error "multiBalanceReport: expected all spans to have an end date")  -- PARTIAL: should not happen |     end = maybe (error "multiBalanceReport: expected all spans to have an end date")  -- PARTIAL: should not happen | ||||||
|             (addDays (-1)) . spanEnd |             (addDays (-1)) . spanEnd | ||||||
|     styles = journalCommodityStyles j |     styles = journalCommodityStyles j | ||||||
|  | |||||||
| @ -76,9 +76,7 @@ postingsReport rspec@ReportSpec{rsOpts=ropts@ReportOpts{..}} j = items | |||||||
|       (precedingps, reportps) = matchedPostingsBeforeAndDuring rspec j reportspan |       (precedingps, reportps) = matchedPostingsBeforeAndDuring rspec j reportspan | ||||||
| 
 | 
 | ||||||
|       -- We may be converting posting amounts to value, per hledger_options.m4.md "Effect of --value on reports". |       -- We may be converting posting amounts to value, per hledger_options.m4.md "Effect of --value on reports". | ||||||
|       -- Strip prices from postings if we won't need them. |       pvalue periodlast = maybe id (postingApplyValuation priceoracle styles periodlast (rsToday rspec)) value_ | ||||||
|       pvalue periodlast = maybeStripPrices . postingApplyCostValuation priceoracle styles periodlast (rsToday rspec) cost_ value_ |  | ||||||
|         where maybeStripPrices = if show_costs_ then id else postingStripPrices |  | ||||||
| 
 | 
 | ||||||
|       -- Postings, or summary postings with their subperiod's end date, to be displayed. |       -- Postings, or summary postings with their subperiod's end date, to be displayed. | ||||||
|       displayps :: [(Posting, Maybe Day)] |       displayps :: [(Posting, Maybe Day)] | ||||||
|  | |||||||
| @ -488,13 +488,14 @@ flat_ = not . tree_ | |||||||
| -- depthFromOpts :: ReportOpts -> Int | -- depthFromOpts :: ReportOpts -> Int | ||||||
| -- depthFromOpts opts = min (fromMaybe 99999 $ depth_ opts) (queryDepth $ queryFromOpts nulldate opts) | -- depthFromOpts opts = min (fromMaybe 99999 $ depth_ opts) (queryDepth $ queryFromOpts nulldate opts) | ||||||
| 
 | 
 | ||||||
| -- | Convert this journal's postings' amounts to cost using their | -- | Convert this journal's postings' amounts to cost using their transaction prices, | ||||||
| -- transaction prices, if specified by options (-B/--cost). | -- if specified by options (-B/--cost). Strip prices if not needed. | ||||||
| -- Maybe soon superseded by newer valuation code. |  | ||||||
| journalSelectingAmountFromOpts :: ReportOpts -> Journal -> Journal | journalSelectingAmountFromOpts :: ReportOpts -> Journal -> Journal | ||||||
| journalSelectingAmountFromOpts opts = case cost_ opts of | journalSelectingAmountFromOpts ropts = maybeStripPrices . case cost_ ropts of | ||||||
|     Cost   -> journalToCost |     Cost   -> journalToCost | ||||||
|     NoCost -> id |     NoCost -> id | ||||||
|  |   where | ||||||
|  |     maybeStripPrices = if show_costs_ ropts then id else journalMapPostingAmounts mixedAmountStripPrices | ||||||
| 
 | 
 | ||||||
| -- | Convert report options to a query, ignoring any non-flag command line arguments. | -- | Convert report options to a query, ignoring any non-flag command line arguments. | ||||||
| queryFromFlags :: ReportOpts -> Query | queryFromFlags :: ReportOpts -> Query | ||||||
|  | |||||||
| @ -83,7 +83,10 @@ tsDraw UIState{aopts=UIOpts{cliopts_=copts@CliOpts{reportspec_=rspec@ReportSpec{ | |||||||
| 
 | 
 | ||||||
|       render . defaultLayout toplabel bottomlabel . str |       render . defaultLayout toplabel bottomlabel . str | ||||||
|         . T.unpack . showTransactionOneLineAmounts |         . T.unpack . showTransactionOneLineAmounts | ||||||
|         $ transactionApplyCostValuation prices styles periodlast (rsToday rspec) (cost_ ropts) (value_ ropts) t |         . maybe id (transactionApplyValuation prices styles periodlast (rsToday rspec)) (value_ ropts) | ||||||
|  |         $ case cost_ ropts of | ||||||
|  |                Cost   -> transactionToCost styles t | ||||||
|  |                NoCost -> t | ||||||
|         -- (if real_ ropts then filterTransactionPostings (Real True) else id) -- filter postings by --real |         -- (if real_ ropts then filterTransactionPostings (Real True) else id) -- filter postings by --real | ||||||
|       where |       where | ||||||
|         toplabel = |         toplabel = | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user