csv: refine unknown accounts more thoroughly, a better fix for #1192
This commit is contained in:
parent
58bb0df5ab
commit
02f2e3bd9b
@ -741,6 +741,7 @@ type CsvRecord = [String]
|
|||||||
showRules rules record =
|
showRules rules record =
|
||||||
unlines $ catMaybes [ (("the "++fld++" rule is: ")++) <$> getEffectiveAssignment rules record fld | fld <- journalfieldnames]
|
unlines $ catMaybes [ (("the "++fld++" rule is: ")++) <$> getEffectiveAssignment rules record fld | fld <- journalfieldnames]
|
||||||
|
|
||||||
|
-- warning: 200 line beast ahead. How to simplify ?
|
||||||
transactionFromCsvRecord :: SourcePos -> CsvRules -> CsvRecord -> Transaction
|
transactionFromCsvRecord :: SourcePos -> CsvRules -> CsvRecord -> Transaction
|
||||||
transactionFromCsvRecord sourcepos rules record = t
|
transactionFromCsvRecord sourcepos rules record = t
|
||||||
where
|
where
|
||||||
@ -803,7 +804,7 @@ transactionFromCsvRecord sourcepos rules record = t
|
|||||||
unknownExpenseAccount = "expenses:unknown"
|
unknownExpenseAccount = "expenses:unknown"
|
||||||
unknownIncomeAccount = "income:unknown"
|
unknownIncomeAccount = "income:unknown"
|
||||||
|
|
||||||
parsePosting' :: String -> JournalFieldName -> JournalFieldName -> JournalFieldName -> JournalFieldName -> JournalFieldName -> JournalFieldName -> Maybe (String, Posting)
|
parsePosting' :: String -> JournalFieldName -> JournalFieldName -> JournalFieldName -> JournalFieldName -> JournalFieldName -> JournalFieldName -> Maybe (Posting, Bool)
|
||||||
parsePosting' number accountFld amountFld amountInFld amountOutFld balanceFld commentFld =
|
parsePosting' number accountFld amountFld amountInFld amountOutFld balanceFld commentFld =
|
||||||
let currency = maybe (fromMaybe "" mdefaultcurrency) render $
|
let currency = maybe (fromMaybe "" mdefaultcurrency) render $
|
||||||
(mfieldtemplate ("currency"++number) `or `mfieldtemplate "currency")
|
(mfieldtemplate ("currency"++number) `or `mfieldtemplate "currency")
|
||||||
@ -812,32 +813,39 @@ transactionFromCsvRecord sourcepos rules record = t
|
|||||||
(mfieldtemplate accountFld `or` mdirective ("default-account" ++ number)))
|
(mfieldtemplate accountFld `or` mdirective ("default-account" ++ number)))
|
||||||
mbalance = (parsebalance currency number.render) =<< mfieldtemplate balanceFld
|
mbalance = (parsebalance currency number.render) =<< mfieldtemplate balanceFld
|
||||||
comment = T.pack $ maybe "" render $ mfieldtemplate commentFld
|
comment = T.pack $ maybe "" render $ mfieldtemplate commentFld
|
||||||
maccount :: Maybe AccountName =
|
|
||||||
|
-- figure out the account name to use for this posting, if any, and
|
||||||
|
-- whether it is the unknown account which may be improved later,
|
||||||
|
-- when we know the posting's final amount.
|
||||||
|
maccountAndIsFinal :: Maybe (AccountName, Bool) =
|
||||||
case maccount' of
|
case maccount' of
|
||||||
-- accountN is set to the empty string - this posting will be suppressed
|
-- accountN is set to the empty string - no posting will be generated
|
||||||
Just "" -> Nothing
|
Just "" -> Nothing
|
||||||
-- accountN is set
|
-- accountN is set (possibly to "expenses:unknown" ! #1192) -
|
||||||
Just a -> Just a
|
-- don't let it be changed.
|
||||||
|
Just a -> Just (a, True)
|
||||||
-- accountN is unset
|
-- accountN is unset
|
||||||
Nothing ->
|
Nothing ->
|
||||||
case (mamount, mbalance) of
|
case (mamount, mbalance) of
|
||||||
-- amountN is set, or implied by balanceN - accountN will be
|
-- amountN is set, or implied by balanceN - set accountN to
|
||||||
-- set to the unknown account (expenses:unknown, for now)
|
-- set to the default unknown account (expenses:unknown)
|
||||||
(Just _, _) -> Just unknownExpenseAccount
|
-- and allow it to be improved later
|
||||||
(_, Just _) -> Just unknownExpenseAccount
|
(Just _, _) -> Just (unknownExpenseAccount, False)
|
||||||
-- amountN is also unset, this posting will be suppressed
|
(_, Just _) -> Just (unknownExpenseAccount, False)
|
||||||
|
-- amountN is also unset - no posting will be generated
|
||||||
(Nothing, Nothing) -> Nothing
|
(Nothing, Nothing) -> Nothing
|
||||||
in
|
in
|
||||||
-- if there's an account N, make a posting N
|
-- if there's an account N, make a posting N
|
||||||
case maccount of
|
case maccountAndIsFinal of
|
||||||
Nothing -> Nothing
|
Nothing -> Nothing
|
||||||
Just acct ->
|
Just (acct, final) ->
|
||||||
Just (number, posting{paccount = accountNameWithoutPostingType acct
|
Just (posting{paccount = accountNameWithoutPostingType acct
|
||||||
,pamount = fromMaybe missingmixedamt mamount
|
,pamount = fromMaybe missingmixedamt mamount
|
||||||
,ptransaction = Just t
|
,ptransaction = Just t
|
||||||
,pbalanceassertion = toAssertion <$> mbalance
|
,pbalanceassertion = toAssertion <$> mbalance
|
||||||
,pcomment = comment
|
,pcomment = comment
|
||||||
,ptype = accountNamePostingType acct})
|
,ptype = accountNamePostingType acct}
|
||||||
|
,final)
|
||||||
|
|
||||||
parsePosting number =
|
parsePosting number =
|
||||||
parsePosting' number
|
parsePosting' number
|
||||||
@ -866,33 +874,40 @@ transactionFromCsvRecord sourcepos rules record = t
|
|||||||
("balance1" `withAlias` "balance")
|
("balance1" `withAlias` "balance")
|
||||||
"comment1" -- comment1 does not have legacy alias
|
"comment1" -- comment1 does not have legacy alias
|
||||||
|
|
||||||
postings' = catMaybes $ posting1:[ parsePosting i | x<-[2..9], let i = show x]
|
postings' = catMaybes $ posting1 : [parsePosting i | x<-[2..9], let i = show x]
|
||||||
|
|
||||||
|
-- Handle some special cases to mimic pre-1.16 behaviour, for
|
||||||
|
-- compatibility; and also, wherever default "unknown" accounts were used,
|
||||||
|
-- refine these based on the sign of the final posting amount.
|
||||||
postings =
|
postings =
|
||||||
case postings' of
|
case postings' of
|
||||||
-- pre-1.16 compatibility: when rules generate just one posting, and
|
-- when rules generate just one posting, and it's a type that needs to
|
||||||
-- it's a type that needs to be balanced, generate the second posting
|
-- be balanced, generate the second posting to balance it.
|
||||||
-- to balance it, with appropriate unknown account name
|
[(p1,final)] ->
|
||||||
[("1",p1)] ->
|
|
||||||
if ptype p1 == VirtualPosting
|
if ptype p1 == VirtualPosting
|
||||||
then [p1]
|
then [p1']
|
||||||
else [p1, p2]
|
else [p1', p2]
|
||||||
where
|
where
|
||||||
p2 = improveUnknownAccountName $
|
p1' = (if final then id else improveUnknownAccountName) p1
|
||||||
|
p2 = improveUnknownAccountName
|
||||||
nullposting{paccount=unknownExpenseAccount
|
nullposting{paccount=unknownExpenseAccount
|
||||||
,pamount=costOfMixedAmount (-pamount p1)
|
,pamount=costOfMixedAmount (-pamount p1)
|
||||||
,ptransaction=Just t}
|
,ptransaction=Just t}
|
||||||
|
|
||||||
-- pre-1.16 compatibility: when rules generate exactly two postings,
|
-- pre-1.16 compatibility: when rules generate exactly two postings,
|
||||||
-- and the second has no amount, give it the balancing amount, and
|
-- and only the second has no amount, give it the balancing amount.
|
||||||
-- refine the account name if it's unknown
|
[(p1,final1), (p2,final2)] ->
|
||||||
[("1",p1), ("2",p2)] ->
|
case (pamount p1 == missingmixedamt, pamount p2 == missingmixedamt) of
|
||||||
case (pamount p1 == missingmixedamt , pamount p2 == missingmixedamt) of
|
(False, True) -> [p1',p2']
|
||||||
(False, True) -> [p1, improveUnknownAccountName $ p2{pamount=costOfMixedAmount(-(pamount p1))}]
|
where p2' = (if final2 then id else improveUnknownAccountName)
|
||||||
_ -> [p1, p2]
|
p2{pamount=costOfMixedAmount(-(pamount p1))}
|
||||||
|
_ -> [p1', p2']
|
||||||
|
where p2' = (if final2 then id else improveUnknownAccountName) p2
|
||||||
|
where
|
||||||
|
p1' = (if final1 then id else improveUnknownAccountName) p1
|
||||||
|
|
||||||
-- otherwise, refine any unknown account names in all postings
|
-- otherwise, refine an unknown account name in all postings.
|
||||||
_ -> map (improveUnknownAccountName . snd) postings'
|
ps -> [(if final then id else improveUnknownAccountName) p | (p,final) <- ps]
|
||||||
where
|
where
|
||||||
-- If this posting has the "expenses:unknown" account name, maybe
|
-- If this posting has the "expenses:unknown" account name, maybe
|
||||||
-- replace that with "income:unknown" now that we know the amount's sign.
|
-- replace that with "income:unknown" now that we know the amount's sign.
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user