From e4263e69e1deb5707d979772f44c30550876b88a Mon Sep 17 00:00:00 2001 From: Simon Michael Date: Sun, 10 Oct 2021 10:33:03 -1000 Subject: [PATCH] areg: begin respecting --date2: show txns' date2 (#1731) --- .../Reports/AccountTransactionsReport.hs | 38 +++++++++++-------- hledger/Hledger/Cli/Commands/Aregister.hs | 20 +++++----- hledger/test/aregister.test | 21 ++++++++++ 3 files changed, 54 insertions(+), 25 deletions(-) diff --git a/hledger-lib/Hledger/Reports/AccountTransactionsReport.hs b/hledger-lib/Hledger/Reports/AccountTransactionsReport.hs index a4cbf69bd..395a336b4 100644 --- a/hledger-lib/Hledger/Reports/AccountTransactionsReport.hs +++ b/hledger-lib/Hledger/Reports/AccountTransactionsReport.hs @@ -103,8 +103,9 @@ accountTransactionsReport rspec@ReportSpec{_rsReportOpts=ropts} j thisacctq = it periodq = Date . periodAsDateSpan $ period_ ropts amtq = filterQuery queryIsCurOrAmt $ _rsQuery rspec queryIsCurOrAmt q = queryIsSym q || queryIsAmt q + wd = whichDate ropts - -- Note that within this functions, we are only allowed limited + -- Note that within this function, we are only allowed limited -- transformation of the transaction postings: this is due to the need to -- pass the original transactions into accountTransactionsReportItem. -- Generally, we either include a transaction in full, or not at all. @@ -112,6 +113,8 @@ accountTransactionsReport rspec@ReportSpec{_rsReportOpts=ropts} j thisacctq = it -- - filter them by the account query if any, -- - discard amounts not matched by the currency and amount query if any, -- - then apply valuation if any. + -- Additional reportq filtering, such as date filtering, happens down in + -- accountTransactionsReportItem, which discards transactions with no matched postings. acctJournal = ptraceAtWith 5 (("ts3:\n"++).pshowTransactions.jtxns) -- maybe convert these transactions to cost or value @@ -149,7 +152,7 @@ accountTransactionsReport rspec@ReportSpec{_rsReportOpts=ropts} j thisacctq = it -- sort by the transaction's register date, then index, for accurate starting balance . ptraceAtWith 5 (("ts4:\n"++).pshowTransactions.map snd) . sortBy (comparing (Down . fst) <> comparing (Down . tindex . snd)) - . map (\t -> (transactionRegisterDate reportq thisacctq t, t)) + . map (\t -> (transactionRegisterDate wd reportq thisacctq t, t)) $ jtxns acctJournal pshowTransactions :: [Transaction] -> String @@ -160,9 +163,8 @@ pshowTransactions = pshow . map (\t -> unwords [show $ tdate t, T.unpack $ tdesc -- which account to use as the focus, a starting balance, and a sign-setting -- function. -- Each transaction is accompanied by the date that should be shown for it --- in the report, which is not necessarily the transaction date; it is --- the earliest of the posting dates which match both thisacctq and reportq, --- otherwise the transaction's date if there are no matching postings. +-- in the report. This is not necessarily the transaction date - see +-- transactionRegisterDate. accountTransactionsReportItems :: Query -> Query -> MixedAmount -> (MixedAmount -> MixedAmount) -> [(Day, Transaction)] -> [AccountTransactionsReportItem] accountTransactionsReportItems reportq thisacctq bal signfn = @@ -176,7 +178,7 @@ accountTransactionsReportItem reportq thisacctq signfn bal (d, torig) | null reportps = (bal, Nothing) -- no matched postings in this transaction, skip it | otherwise = (b, Just (torig, tacct{tdate=d}, numotheraccts > 1, otheracctstr, a, b)) where - tacct@Transaction{tpostings=reportps} = filterTransactionPostings reportq torig + tacct@Transaction{tpostings=reportps} = filterTransactionPostings reportq torig -- TODO needs to consider --date2, #1731 (thisacctps, otheracctps) = partition (matchesPosting thisacctq) reportps numotheraccts = length $ nub $ map paccount otheracctps otheracctstr | thisacctq == None = summarisePostingAccounts reportps -- no current account ? summarise all matched postings @@ -185,16 +187,20 @@ accountTransactionsReportItem reportq thisacctq signfn bal (d, torig) a = signfn . maNegate $ sumPostings thisacctps b = bal `maPlus` a --- | What is the transaction's date in the context of a particular account --- (specified with a query) and report query, as in an account register ? --- It's normally the transaction's general date, but if any posting(s) --- matched by the report query and affecting the matched account(s) have --- their own earlier dates, it's the earliest of these dates. --- Secondary transaction/posting dates are ignored. -transactionRegisterDate :: Query -> Query -> Transaction -> Day -transactionRegisterDate reportq thisacctq t - | null thisacctps = tdate t - | otherwise = minimum $ map postingDate thisacctps +-- TODO needs checking, cf #1731 +-- | What date should be shown for a transaction in an account register report ? +-- This will be in context of a particular account (the "this account" query) +-- and any additional report query. It could be: +-- +-- - if postings are matched by both thisacctq and reportq, the earliest of those +-- matched postings' dates (or their secondary dates if --date2 was used) +-- +-- - the transaction date, or its secondary date if --date2 was used. +-- +transactionRegisterDate :: WhichDate -> Query -> Query -> Transaction -> Day +transactionRegisterDate wd reportq thisacctq t + | not $ null thisacctps = minimum $ map (postingDateOrDate2 wd) thisacctps + | otherwise = transactionDateOrDate2 wd t where reportps = tpostings $ filterTransactionPostings reportq t thisacctps = filter (matchesPosting thisacctq) reportps diff --git a/hledger/Hledger/Cli/Commands/Aregister.hs b/hledger/Hledger/Cli/Commands/Aregister.hs index 8e4e44344..556888ab6 100644 --- a/hledger/Hledger/Cli/Commands/Aregister.hs +++ b/hledger/Hledger/Cli/Commands/Aregister.hs @@ -88,6 +88,7 @@ aregister opts@CliOpts{rawopts_=rawopts,reportspec_=rspec} j = do , balanceaccum_= Historical , querystring_ = querystring } + wd = whichDate ropts' -- and regenerate the ReportSpec, making sure to use the above rspec' <- either fail return $ updateReportSpec ropts' rspec let @@ -98,7 +99,7 @@ aregister opts@CliOpts{rawopts_=rawopts,reportspec_=rspec} j = do reverse items -- select renderer render | fmt=="txt" = accountTransactionsReportAsText opts (_rsQuery rspec') thisacctq - | fmt=="csv" = printCSV . accountTransactionsReportAsCsv (_rsQuery rspec') thisacctq + | fmt=="csv" = printCSV . accountTransactionsReportAsCsv wd (_rsQuery rspec') thisacctq | fmt=="json" = toJsonText | otherwise = error' $ unsupportedOutputFormatError fmt -- PARTIAL: where @@ -106,19 +107,19 @@ aregister opts@CliOpts{rawopts_=rawopts,reportspec_=rspec} j = do writeOutputLazyText opts $ render items' -accountTransactionsReportAsCsv :: Query -> Query -> AccountTransactionsReport -> CSV -accountTransactionsReportAsCsv reportq thisacctq is = +accountTransactionsReportAsCsv :: WhichDate -> Query -> Query -> AccountTransactionsReport -> CSV +accountTransactionsReportAsCsv wd reportq thisacctq is = ["txnidx","date","code","description","otheraccounts","change","balance"] - : map (accountTransactionsReportItemAsCsvRecord reportq thisacctq) is + : map (accountTransactionsReportItemAsCsvRecord wd reportq thisacctq) is -accountTransactionsReportItemAsCsvRecord :: Query -> Query -> AccountTransactionsReportItem -> CsvRecord +accountTransactionsReportItemAsCsvRecord :: WhichDate -> Query -> Query -> AccountTransactionsReportItem -> CsvRecord accountTransactionsReportItemAsCsvRecord - reportq thisacctq + wd reportq thisacctq (t@Transaction{tindex,tcode,tdescription}, _, _issplit, otheracctsstr, change, balance) = [idx,date,tcode,tdescription,otheracctsstr,amt,bal] where idx = T.pack $ show tindex - date = showDate $ transactionRegisterDate reportq thisacctq t + date = showDate $ transactionRegisterDate wd reportq thisacctq t amt = wbToText $ showMixedAmountB oneLine change bal = wbToText $ showMixedAmountB oneLine balance @@ -156,7 +157,7 @@ accountTransactionsReportAsText copts reportq thisacctq items = TB.toLazyText $ -- accountTransactionsReportItemAsText :: CliOpts -> Query -> Query -> Int -> Int -> AccountTransactionsReportItem -> TB.Builder accountTransactionsReportItemAsText - copts@CliOpts{reportspec_=ReportSpec{_rsReportOpts=ReportOpts{color_}}} + copts@CliOpts{reportspec_=ReportSpec{_rsReportOpts=ropts@ReportOpts{color_}}} reportq thisacctq preferredamtwidth preferredbalwidth (t@Transaction{tdescription}, _, _issplit, otheracctsstr, change, balance) = -- Transaction -- the transaction, unmodified @@ -184,7 +185,8 @@ accountTransactionsReportItemAsText where w = fullwidth - wbWidth amt -- calculate widths (totalwidth,mdescwidth) = registerWidthsFromOpts copts - (datewidth, date) = (10, showDate $ transactionRegisterDate reportq thisacctq t) + (datewidth, date) = (10, showDate $ transactionRegisterDate wd reportq thisacctq t) + where wd = whichDate ropts (amtwidth, balwidth) | shortfall <= 0 = (preferredamtwidth, preferredbalwidth) | otherwise = (adjustedamtwidth, adjustedbalwidth) diff --git a/hledger/test/aregister.test b/hledger/test/aregister.test index 2eccac6dd..0d0ba9d3a 100644 --- a/hledger/test/aregister.test +++ b/hledger/test/aregister.test @@ -100,3 +100,24 @@ Transactions in a and subaccounts: -1 B 1 C +# aregister respects --date2 (#1731). +< +2021-01-01=2021-02-02 + (a) 1 + +# 7. With --date2, it should show the secondary transaction date. +$ hledger -f- areg a --date2 +Transactions in a and subaccounts: +2021-02-02 a 1 1 + +# # 8. With --date2, it should match on the secondary transaction date. +# $ hledger -f- areg a --date2 date:202102 +# 2021-02-02 a 1 1 + +# # 9. ditto +# $ hledger -f- areg a --date2 date2:202102 +# 2021-02-02 a 1 1 + +# # 10. should show the transaction, with the january date (?) +# $ hledger -f- areg a date2:202102 +# 2021-01-01 a 1 1