areg: begin respecting --date2: show txns' date2 (#1731)

This commit is contained in:
Simon Michael 2021-10-10 10:33:03 -10:00
parent b4c1188c26
commit e4263e69e1
3 changed files with 54 additions and 25 deletions

View File

@ -103,8 +103,9 @@ accountTransactionsReport rspec@ReportSpec{_rsReportOpts=ropts} j thisacctq = it
periodq = Date . periodAsDateSpan $ period_ ropts periodq = Date . periodAsDateSpan $ period_ ropts
amtq = filterQuery queryIsCurOrAmt $ _rsQuery rspec amtq = filterQuery queryIsCurOrAmt $ _rsQuery rspec
queryIsCurOrAmt q = queryIsSym q || queryIsAmt q 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 -- transformation of the transaction postings: this is due to the need to
-- pass the original transactions into accountTransactionsReportItem. -- pass the original transactions into accountTransactionsReportItem.
-- Generally, we either include a transaction in full, or not at all. -- 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, -- - filter them by the account query if any,
-- - discard amounts not matched by the currency and amount query if any, -- - discard amounts not matched by the currency and amount query if any,
-- - then apply valuation 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 = acctJournal =
ptraceAtWith 5 (("ts3:\n"++).pshowTransactions.jtxns) ptraceAtWith 5 (("ts3:\n"++).pshowTransactions.jtxns)
-- maybe convert these transactions to cost or value -- 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 -- sort by the transaction's register date, then index, for accurate starting balance
. ptraceAtWith 5 (("ts4:\n"++).pshowTransactions.map snd) . ptraceAtWith 5 (("ts4:\n"++).pshowTransactions.map snd)
. sortBy (comparing (Down . fst) <> comparing (Down . tindex . 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 $ jtxns acctJournal
pshowTransactions :: [Transaction] -> String 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 -- which account to use as the focus, a starting balance, and a sign-setting
-- function. -- function.
-- Each transaction is accompanied by the date that should be shown for it -- 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 -- in the report. This is not necessarily the transaction date - see
-- the earliest of the posting dates which match both thisacctq and reportq, -- transactionRegisterDate.
-- otherwise the transaction's date if there are no matching postings.
accountTransactionsReportItems :: Query -> Query -> MixedAmount -> (MixedAmount -> MixedAmount) accountTransactionsReportItems :: Query -> Query -> MixedAmount -> (MixedAmount -> MixedAmount)
-> [(Day, Transaction)] -> [AccountTransactionsReportItem] -> [(Day, Transaction)] -> [AccountTransactionsReportItem]
accountTransactionsReportItems reportq thisacctq bal signfn = 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 | null reportps = (bal, Nothing) -- no matched postings in this transaction, skip it
| otherwise = (b, Just (torig, tacct{tdate=d}, numotheraccts > 1, otheracctstr, a, b)) | otherwise = (b, Just (torig, tacct{tdate=d}, numotheraccts > 1, otheracctstr, a, b))
where 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 (thisacctps, otheracctps) = partition (matchesPosting thisacctq) reportps
numotheraccts = length $ nub $ map paccount otheracctps numotheraccts = length $ nub $ map paccount otheracctps
otheracctstr | thisacctq == None = summarisePostingAccounts reportps -- no current account ? summarise all matched postings 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 a = signfn . maNegate $ sumPostings thisacctps
b = bal `maPlus` a b = bal `maPlus` a
-- | What is the transaction's date in the context of a particular account -- TODO needs checking, cf #1731
-- (specified with a query) and report query, as in an account register ? -- | What date should be shown for a transaction in an account register report ?
-- It's normally the transaction's general date, but if any posting(s) -- This will be in context of a particular account (the "this account" query)
-- matched by the report query and affecting the matched account(s) have -- and any additional report query. It could be:
-- their own earlier dates, it's the earliest of these dates. --
-- Secondary transaction/posting dates are ignored. -- - if postings are matched by both thisacctq and reportq, the earliest of those
transactionRegisterDate :: Query -> Query -> Transaction -> Day -- matched postings' dates (or their secondary dates if --date2 was used)
transactionRegisterDate reportq thisacctq t --
| null thisacctps = tdate t -- - the transaction date, or its secondary date if --date2 was used.
| otherwise = minimum $ map postingDate thisacctps --
transactionRegisterDate :: WhichDate -> Query -> Query -> Transaction -> Day
transactionRegisterDate wd reportq thisacctq t
| not $ null thisacctps = minimum $ map (postingDateOrDate2 wd) thisacctps
| otherwise = transactionDateOrDate2 wd t
where where
reportps = tpostings $ filterTransactionPostings reportq t reportps = tpostings $ filterTransactionPostings reportq t
thisacctps = filter (matchesPosting thisacctq) reportps thisacctps = filter (matchesPosting thisacctq) reportps

View File

@ -88,6 +88,7 @@ aregister opts@CliOpts{rawopts_=rawopts,reportspec_=rspec} j = do
, balanceaccum_= Historical , balanceaccum_= Historical
, querystring_ = querystring , querystring_ = querystring
} }
wd = whichDate ropts'
-- and regenerate the ReportSpec, making sure to use the above -- and regenerate the ReportSpec, making sure to use the above
rspec' <- either fail return $ updateReportSpec ropts' rspec rspec' <- either fail return $ updateReportSpec ropts' rspec
let let
@ -98,7 +99,7 @@ aregister opts@CliOpts{rawopts_=rawopts,reportspec_=rspec} j = do
reverse items reverse items
-- select renderer -- select renderer
render | fmt=="txt" = accountTransactionsReportAsText opts (_rsQuery rspec') thisacctq 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 | fmt=="json" = toJsonText
| otherwise = error' $ unsupportedOutputFormatError fmt -- PARTIAL: | otherwise = error' $ unsupportedOutputFormatError fmt -- PARTIAL:
where where
@ -106,19 +107,19 @@ aregister opts@CliOpts{rawopts_=rawopts,reportspec_=rspec} j = do
writeOutputLazyText opts $ render items' writeOutputLazyText opts $ render items'
accountTransactionsReportAsCsv :: Query -> Query -> AccountTransactionsReport -> CSV accountTransactionsReportAsCsv :: WhichDate -> Query -> Query -> AccountTransactionsReport -> CSV
accountTransactionsReportAsCsv reportq thisacctq is = accountTransactionsReportAsCsv wd reportq thisacctq is =
["txnidx","date","code","description","otheraccounts","change","balance"] ["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 accountTransactionsReportItemAsCsvRecord
reportq thisacctq wd reportq thisacctq
(t@Transaction{tindex,tcode,tdescription}, _, _issplit, otheracctsstr, change, balance) (t@Transaction{tindex,tcode,tdescription}, _, _issplit, otheracctsstr, change, balance)
= [idx,date,tcode,tdescription,otheracctsstr,amt,bal] = [idx,date,tcode,tdescription,otheracctsstr,amt,bal]
where where
idx = T.pack $ show tindex idx = T.pack $ show tindex
date = showDate $ transactionRegisterDate reportq thisacctq t date = showDate $ transactionRegisterDate wd reportq thisacctq t
amt = wbToText $ showMixedAmountB oneLine change amt = wbToText $ showMixedAmountB oneLine change
bal = wbToText $ showMixedAmountB oneLine balance 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 :: CliOpts -> Query -> Query -> Int -> Int -> AccountTransactionsReportItem -> TB.Builder
accountTransactionsReportItemAsText accountTransactionsReportItemAsText
copts@CliOpts{reportspec_=ReportSpec{_rsReportOpts=ReportOpts{color_}}} copts@CliOpts{reportspec_=ReportSpec{_rsReportOpts=ropts@ReportOpts{color_}}}
reportq thisacctq preferredamtwidth preferredbalwidth reportq thisacctq preferredamtwidth preferredbalwidth
(t@Transaction{tdescription}, _, _issplit, otheracctsstr, change, balance) = (t@Transaction{tdescription}, _, _issplit, otheracctsstr, change, balance) =
-- Transaction -- the transaction, unmodified -- Transaction -- the transaction, unmodified
@ -184,7 +185,8 @@ accountTransactionsReportItemAsText
where w = fullwidth - wbWidth amt where w = fullwidth - wbWidth amt
-- calculate widths -- calculate widths
(totalwidth,mdescwidth) = registerWidthsFromOpts copts (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) (amtwidth, balwidth)
| shortfall <= 0 = (preferredamtwidth, preferredbalwidth) | shortfall <= 0 = (preferredamtwidth, preferredbalwidth)
| otherwise = (adjustedamtwidth, adjustedbalwidth) | otherwise = (adjustedamtwidth, adjustedbalwidth)

View File

@ -100,3 +100,24 @@ Transactions in a and subaccounts:
-1 B -1 B
1 C 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